如何使用实体框架的导航属性来构建视图模型

Posted

技术标签:

【中文标题】如何使用实体框架的导航属性来构建视图模型【英文标题】:How to use Entity Framework's Navigation Properties to build a View Model 【发布时间】:2014-03-17 19:47:17 【问题描述】:

我无法为基于 EF 的模型找到正确的映射架构。

我有一个给定的序列号(设备),我想创建一个视图模型,其中包含所有相关图像及其各自的类别。我最近才添加类别,这就是我的问题开始的地方。在那之前,我只是用

选择了相关的设备

dbCon.Devices.SingleOrDefault(d => d.serial == serial)

然后,使用 Automapper 将其 Images 属性映射到视图模型中的图像列表。现在我基本上想创建一个包含所有相关类别的列表,以及它们相关图像的各自集合。但是我不知道如何开始。我用什么来代替我的初始设备?我只想接收包含与定义的设备相关的图像的类别。

我想我可以弄清楚如何循环执行(循环所有图像并将它们各自的类别添加到列表中),但我认为它不仅会链接到与设备相关的图像,而且到与该类别相关的所有图像。另外我的印象是,使用 ORM 在处理数据之前我不需要循环。

【问题讨论】:

您正在使用 EF。使用导航属性来选择你想要的。 【参考方案1】:

我有一个给定的序列号(设备),我想创建一个视图模型 包含所有相关图像及其各自的类别。

使用导航属性:

// Get Device
Device device = dbCon.Devices.SingleOrDefault(d => d.serial == serial);

// Get Device's Images
IQueryable<Image> images = device.Images;

// Get Images Categories
IQueryable<Category> categories = images.Select(c => c.Category);

您的视图模型看起来像:

class DeviceImageCategoriesViewModel

    Device Device  get; set; 
    List<Category> Categories  get; set; 


var viewModel = new DeviceImageCategoriesViewModel

    Device = device,
    Categories = categories.ToList() // Each Category will have its navigation property back to Images
;

或者通过使用预先加载:

Device device = dbCon.Devices.SingleOrDefault(d => d.serial == serial) 
                             .Include(i => i.Images.Select(c => c.Categories)) 
                             .ToList(); 

List<Category> categories = device.Images.Select(c => c.Categories);

【讨论】:

首先让我感谢您的努力。我不确定我是否正确采用了你的代码,但它至少给了我设备、正确的分配图像列表和类别列表。但是,当导航到类别时,它们包含所有图像,而不仅仅是选择的来源。这是我必须忍受的事情并手动检查是否实际分配了引用的图像,还是有一个技巧可以自动过滤掉这些图像? 这就是您的数据库架构。如果您想从类别返回图像,则必须手动过滤它们。 我最终将每个类别的图像属性与图像的一般列表相交。这从类别列表中删除了所有未分配的图像。

以上是关于如何使用实体框架的导航属性来构建视图模型的主要内容,如果未能解决你的问题,请参考以下文章

实体框架对导航属性的约束

在导航属性实体框架上正确使用接口

如何首先使用实体​​框架 5 代码删除具有导航属性的对象?

实体框架Linq查询:如何在多个导航属性上从何处选择并从第三个导航属性中选择

如何使用代码优先实体框架在 ASP.Net MVC3 中重新加载多对多导航属性

使用实体框架的导航属性的有意义的名称