C# 创建LINQ到实体可以转换的属性

C# 创建LINQ到实体可以转换的属性,c#,.net,entity-framework,linq-to-entities,C#,.net,Entity Framework,Linq To Entities,我很好奇如何创建一个可以由LINQ翻译的属性。下面是一个非常简单的例子 我有一个表/类Category,它有一个列ParentId链接到它自己(因此一个类别可以有子类别) EF自动生成一个属性类别1,它是父类别 为了清晰起见,我创建了另一个属性 public partial class Category { public Category Parent { get { return Category1; } } } 问题是,这是可行的 var categs = ctx.Ca

我很好奇如何创建一个可以由LINQ翻译的属性。下面是一个非常简单的例子

我有一个表/类
Category
,它有一个列
ParentId
链接到它自己(因此一个类别可以有子类别)

EF自动生成一个属性
类别1
,它是父类别

为了清晰起见,我创建了另一个属性

public partial class Category
{
  public Category Parent
  {
    get { return Category1; }
  }
}
问题是,这是可行的

var categs = ctx.Categories.Where(x => x.Category1 == null);
但这不起作用

var categs = ctx.Categories.Where(x => x.Parent == null);
LINQ to实体中不支持指定的类型成员“Parent”。仅支持初始值设定项、实体成员和实体导航属性

有没有办法不使用.ToList()创建可翻译属性(LINQ到SQL)


编辑:我希望避免接触Model.edmx,因为数据库在开发过程中经常更改,.edmx经常需要在实体数据模型设计器(.edmx文件)中重新创建,如果您询问是否可以使用getter/setter中的任何C#代码创建属性,并在以后通过标准LINQ将其理解为实体,则可以将
类别1
重命名为
父级

。C#比SQL更具表现力,期望实体框架充当通用的C#to SQL转换器是不合理的

但是,您可以在许多情况下解决这个问题,请参见示例

更新

如果你告诉我们你到底想要实现什么,这会有所帮助,但下面是一个例子:

public partial class Category
{
    public static Expression<Func<Category, bool>> ParentIsNullExpression
    {
        get 
        {
            return c => c.Category1 == null;
        }
    }
}
可以对表达式进行各种操作,其中一些操作受EF支持,因此可以转换为SQL。

您有4个选项:

  • 首先使用代码
  • 将其添加到EDMX设计器
  • 将属性添加到EDMX的CSDL部分,将列添加到EDMX的SSDL部分,然后在EDMX的映射部分将它们相互映射
  • 使用.ToList()将查询放入内存,然后使用内部LINQ而不是LINQ to实体

  • 您需要创建一个从类别到父类别的导航属性,就像foreign keyHi Cold告诉您的一样,抱歉,我不确定您的意思。已经有一个外键(否则EF不会创建Category1)您是否实际查看了Model.Designer.cs和/或Reflector中的
    Category1
    ,以查看在其定义中添加了哪些属性或其他工具?是的,但我不理解,我尝试复制它们,但没有成功这只是一个非常简单的示例。我问的是如何编写属性,而不是重命名现有属性。不管怎样,谢谢。这不能用C完成吗?但是Model.Designer.cs本身(EDMX的cs文件)是C#,不是吗??您是指从该链接返回表达式的属性吗?我来看看。是的,我指的是表达式属性。使其在Model.Designer.cs中工作的不是属性代码,而是用于访问属性的表达式,例如
    c=>c.Category
    。EF知道您需要
    Category
    属性,并将其转换为
    Category
    列/表。很抱歉,我从未使用过表达式属性。您是说表达式属性有可能被转换为SQL吗?可以用表达式属性替换我问题中的父属性,以便LINQ可以转换它吗?谢谢你,我很有趣!谢谢Jacek的完整回答!顺便说一句
    var categs = ctx.Categories.Where(Category.ParentIsNullExpression);