将“成员”转换为SQL,因此它不会抛出“没有支持的SQL转换”

时间:2013-03-05 04:24:50

标签: c# asp.net linq-to-sql

我最近一直在升级我的数据库并收到此错误

基本上我所做的是以下内容:

我有一个Participants表,其中包含NameFirst NameE-mail address,... 现在我将其重构为Persons表和Participants表。每个participant都通过UUID链接到person。 我已从Name表中删除了First Nameparticipants,现在它们位于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

2 个答案:

答案 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);
    } 
}