IQueryable 实体框架 POCO 映射

Posted

技术标签:

【中文标题】IQueryable 实体框架 POCO 映射【英文标题】:IQueryable Entity Framework POCO Mappings 【发布时间】:2011-05-06 11:05:17 【问题描述】:

我正在使用带有 EF4 的 ASP.NET MVC2。我需要为我的两个类 PersonP 和 AddressP 创建 POCO,它们对应于它们的 EF4“复杂”类(包括导航属性和 OnPropertyChanged() 等内容)。仅映射 PersonP 本身可以正常工作,但 PersonP 包含 AddressP(外键) - 如何使用 IQueryable 表达式映射它?

这是我尝试过的:

class AddressP

 int Id  get; set; 
 string Street  get; set; 


class PersonP

 int Id  get; set; 
 string FirstName  get; set; 
 AddressP Address  get; set; 


IQueryable<PersonP> persons = _repo.QueryAll()
    .Include("Address")
    .Select(p => new PersonP

 Id = p.Id,
 FirstName = p.FirstName,
 //Address = p.Address <-- I'd like to do this, but p.Address is Address, not AddressP
 //Address = (p.Address == null) ? null :
 //new AddressP    <-- does not work; can't use CLR object in LINQ runtime expression
 //
 // Id = p.Address.Id,
 // Street = p.Address.Street
 //
);

    如果没有.Include("Address"),我将无法从地址表中检索任何内容,这是否正确?

    如何使用上面的Select() 语句将Address 映射到PersonP 内的AddressP

谢谢。

【问题讨论】:

【参考方案1】:
    这是正确的,如果您禁用了延迟加载,或者您的对象上下文已经被释放并且不能用于使延迟加载工作。 是的,它不起作用,因为首先您需要执行查询然后开始映射它,否则您的映射逻辑将被视为在数据库中运行,因此会出现异常。 这样的事情会起作用:
// First we execute the query:
IQueryable<PersonP> persons = _repo.QueryAll().Include("Address").ToList();

// Now we have a IEnumerable and we can safely do the mappings:
persons.Select(p => new PersonP

    Id = p.Id,
    FirstName = p.FirstName,
    Address = (p.Address == null) ? null : new AddressP()
    
        Id = p.Address.Id,
        Street = p.Address.Street
    
).ToList();

虽然此解决方案可以解决问题,但如果打算使用 POCO 类,您绝对应该考虑利用 EF4.0 POCO 支持并直接将 POCO 类与 EF 一起使用,而不是事后映射它们。一个很好的起点是这个演练: Walkthrough: POCO Template for the Entity Framework

【讨论】:

感谢您的回复,这正是我想要的。不幸的是,我必须将其保留为 IQueryable,因为我必须使用第三方方法应用过滤器/排序/分组,并且人员/地址存储库可能很大 - 所以我必须在执行实际查询之前执行此操作。我将研究 POCO EF4 支持 - 根据您的经验,您会推荐 NHibernate 解决方案吗? 我没有任何使用 NHibernate 的经验,但我认为不会有任何不同。您也可以查看 AsQueryable 以查看是否可以使用它,但我仍然认为 POCO 是在这种情况下要走的路。

以上是关于IQueryable 实体框架 POCO 映射的主要内容,如果未能解决你的问题,请参考以下文章

没有主键和空列的表上的实体框架反向 poco

将 IQueryable where 子句从 DTO 映射到实体

在紧凑框架上映射对象

实体框架代码优先 IQueryable

实体框架中的 POCO 是啥? [关闭]

试图模拟 IQueryable 实体框架查询