部分加载Entity Framework实体并将它们传递给表示层

时间:2011-12-21 12:24:15

标签: asp.net-mvc-3 entity-framework entity-framework-4.1 repository-pattern

如果我想在检索EF实体的数据时只选择几列并将它们转换为实体类型,我无法这样做,因为它会抛出此帖子中提到的错误 The entity cannot be constructed in a LINQ to Entities query。我不想选择所有列,因为我只需要很少的列。我可以使用匿名类型,但如果我使用存储库模式并希望将所有数据访问代码封装在存储库对象中并将强类型对象集合传递给控制器​​(而不是匿名对象集合),我该如何实现?是为EF实体的每个属性子集定义DTO对象的唯一选项吗?我知道存在部分加载实体丢失数据的风险,但如果我准备承担风险并希望完全控制数据更新,那是不可能的?

例如我想要" ProductRepository"方法签名就像这样

public IEnumerable<Product> GetProducts(int categoryID) //selection of subset of data

我希望将此产品集合从控制器传递到视图(在ASP.NET MVC项目中),并且在视图中我想要具有强类型模型(使用intellisense)对象。这可能吗?如果没有,由于这个限制,我可能不得不重新考虑使用EF作为我的项目。我使用的是EF 4.1版本。

2 个答案:

答案 0 :(得分:1)

是的,使用视图模型而不是实体完全可以实现。以下是控制器代码示例:

var productEntities = productRepos.GetProducts(6);
var productViewModels = Automapper.Mapper
    .Map<IEnumerable<ProductViewModel>>(productEntities);
return View(productViewModels);

您的视图模型将只包含视图所需的属性。查看automapper。

答案 1 :(得分:1)

是的,在这种情况下,选项是您要选择的每个属性子集的特殊对象。您可以调用对象DTO,因为它只是投影的结果。这是正确的方法,因为如果您的UI不需要实体类型的其他属性,则只传递专门的ViewModel是正确的。

另一个更复杂(也更糟糕)的选择是在Linq-to-entities查询中选择匿名类型,调用ToList并在构造之后选择真实实体类型。不允许部分实体选择,也不允许投影到映射的实体类型。这就是为什么你必须使用这种繁琐的方法。例如:

// Select anonymous projection
var query = from x in context.Entities
            where ...
            select new { ... };

// Repopulate entity type
var reultSet = query.ToList().Select(x => new Entity { ... });