【问题标题】:EF Code First - Eager Loading and Filtering Subclass Properties (Inheritance)EF Code First - 急切加载和过滤子类属性(继承)
【发布时间】:2013-03-16 17:13:10
【问题描述】:

我有以下课程(过于简化):

public class Person
{
    public int ID { get; set; }
}
public class Content
{
    public int ID { get; set; }
}
public class Image : Content
{
    public bool Private { get; set; }
    public Person Author { get; set; }
}
public class Tag
{
    public int ID { get; set; }
    public Content Content { get; set; }
    public Person Person { get; set; }
}

我想获取所有Tags,其中ContentImage,而Image 不是Private(同时急切地加载Image 的属性)。尝试这样做但不起作用的示例:

var tags = context.Tags
    .Include("Content.Author")
    .Include("Person")
    .Where(t => !((Image)t.Content).Private);

我收到以下错误:

无法将类型“内容”转换为类型“图像”。 LINQ to Entities 仅支持转换 EDM 基元或枚举类型。

并且删除了Where 子句:

指定的包含路径无效。 EntityType“内容”未声明名为“作者”的导航属性。

我需要什么样的查询和/或模型架构更改才能完成这种方法?

【问题讨论】:

  • 不是答案,但请尝试将您的急切加载与 Lambda 包含一起使用。添加 using 语句 System.Data.Entity 并且您的 Include 应该是 context.Tags.Include(t => t.Content.Author).Include(t => t.Person)
  • @Patrick 我在尝试使用 EF 5.0 使用任何 lambda Include() 时遇到编译器错误。我还需要其他什么东西才能使用它们吗?
  • 您是否尝试过右键单击您的项目,添加引用,然后在“程序集”菜单选择框架的弹出对话框中,搜索 System.Data 并从那里包含它,看看是否有效。 - i.imgur.com/zr9kr70.png
  • @PatrickMagee 我能够让 lambda 工作,作者:using System.Data.Entity; 不幸的是,我遇到了与以前相同的错误:指定的包含路径无效。 EntityType“内容”未声明名为“作者”的导航属性。这也不能解决Where 子句问题。
  • 它可能是在尝试投射到 system.drawing.image 吗?

标签: c# entity-framework inheritance ef-code-first


【解决方案1】:

您可以在Where 子句中编写过滤器,方式如下:

.Where(t => t.Content is Image && !(t.Content as Image).Private)

然而,更大的问题是Include 部分。 Author 属性仅存在于派生类型ImageInclude 将尝试加载基本类型Content(它没有Author 属性),因为这是导航属性@987654330 的类型@在Tag。你不能在这里使用Include

您可以尝试将查询重写为投影:

var tags = context.Tags
    .Where(t => t.Content is Image && !(t.Content as Image).Private)
    .Select(t => new
    {
        Tag = t,
        Image = t.Content as Image, // possibly this line is not needed
        Author = (t.Content as Image).Author,
        Person = t.Person
    })
    .AsEnumerable()
    .Select(x => x.Tag)
    .ToList();

只要您不禁用更改跟踪(例如 AsNoTracking),EF 应该自动将对象图放在一起,以便加载的标签具有填充的 ContentContent.AuthorPerson 属性( 好像你已经用Include加载了导航属性。

顺便说一句:请求包含派生类型的导航属性的功能here on UserVoice。这和你的情况不完全一样,但在评论部分甚至是对你的场景的请求。

【讨论】:

  • 这非常有效!感谢您的回答和 UserVoice 功能的链接。
【解决方案2】:

尝试将类定义更改为...

class Person
{
  public int ID { get; set; }
}

class Content
{
  public int ID { get; set; }
}

class Image : Content
{
  public bool IsPrivate { get; set; }   
  public virtual Person Author { get; set; }
}

class Tag
{
public int ID { get; set; }
public Content Content { get; set; }
public Person Person { get; set; }
}

私有似乎不是一个好名称,因为它与公共或私有声明冲突。

【讨论】:

    猜你喜欢
    • 2012-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多