我最近一直在升级我的数据库并收到此错误
基本上我所做的是以下内容:
我有一个Participants
表,其中包含Name
,First Name
,E-mail address
,...
现在我将其重构为Persons
表和Participants
表。每个participant
都通过UUID链接到person
。
我已从Name
表中删除了First Name
和participants
,现在它们位于Persons
表中。
在我的参与者部分课程中:
public partial class Participant {
public string Name {
get {
return this.Person.Name;
}
}
public string FirstName {
get {
return this.Person.FirstName;
}
}
}
所以现在我的整个项目仍然可以找到名称,而且我不必一次编辑大量代码。
但是以下问题让我陷入困境:
_db.Participants.Where(q => whatever).OrderBy(q => q.Name).ThenBy(q => q.FirstName).ToList();
这引发了臭名昭着的The member 'xxx.Models.Participants.Name' has no supported translation to SQL
有没有办法简单告诉SQL生成器Participants.Name
实际上是Participants.Person.Name
?
答案 0 :(得分:2)
免责声明:如果您这样做是为了能够使用以前编写的查询而不进行修改,那么您将非常幸运。但是,如果您正在进行封装和代码管理,请继续阅读。
有一种方法,但它有点笨重。
首先,您必须向Participant
类添加表达式(因为LINQ和EF使用表达式,而不是已编译的代码):
public partial class Participant
{
public static readonly Expression<Func<Participant, string>>
NameExpression = p => p.Person.Name;
public static readonly Expression<Func<Participant, string>>
FirstNameExpression = p => p.Person.FirstName;
您可以按照目前的方式继续使用您的媒体资源:
[NotMapped]
public string Name
{
get
{
return this.Person.Name;
}
}
或者,为了减少代码重复,可以引用静态表达式:
[NotMapped]
public string FirstName
{
get
{
return Participant.FirstNameExpression.Compile().Invoke(this);
// if you do this, you might want to consider caching the delegate
// returned by Expression.Compile()
}
}
}
最后,当您创建LINQ查询时,您将不得不使用lambda语法,但您可以使用您在直接写入查询的临时表达式中制作的表达式:
IEnumerable<Participant> participants = _db.Participants
// .Where(q => whatever)
.OrderBy(Participant.NameExpression)
.ThenBy(Participant.FirstNameExpression)
.ToList();
答案 1 :(得分:1)
如果我还要编辑查询,我也可以使用扩展程序:
public static class MyExtensions {
public static IQueryable<Participant> InDefaultOrder(this IQueryable<Participant> source) {
return source.OrderBy(q => q.Person.Name).ThenBy(q => q.Person.FirstName);
}
}
然后我的查询就是:_db.Participants.Where(q => whatever).InDefaultOrder().ToList();
如果它发生变化,就很容易编辑和维护。
---编辑---
我还必须添加这个
public static class MyExtensions {
public static IEnumerable<Participant> InDefaultOrder(this IEnumerable<Participant> source) {
return source.OrderBy(q => q.Person.Name).ThenBy(q => q.Person.FirstName);
}
}