将EF实体映射到视图模型,维护集合和延迟加载

本文关键字:维护 集合 延迟加载 模型 视图 EF 实体 映射 | 更新日期: 2023-09-27 18:02:41

这是自EF 6以来一直困扰我的事情。现在,我们如何将集合映射到视图模型,以便使用IEnumerables进行映射更改时不会感到痛苦呢?下面的代码片段演示了我的问题:

Entity - SS.Entity.Event

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<SS.Entity.User> Broadcasters { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<SS.Entity.User> Viewers { get; set; }

Model - SS.Model.Event

public virtual ICollection<SS.Model.User> Broadcasters { get; set; }
public virtual ICollection<SS.Model.User> Viewers { get; set; }

集合修改后映射回实体

Broadcasters = e.Broadcasters.Select(u => new SS.Entity.User
{
    Id = u.Id,
    SkypeId = u.SkypeId,
    Name = u.Name
}).ToList(), // THIS IS THE PROBLEM
Viewers = e.Viewers.Select(u => new SS.Entity.User
{
    Id = u.Id,
    SkypeId = u.SkypeId,
    Name = u.Name
}).ToList() // THIS IS THE PROBLEM

这个问题是我不能将一个ICollection映射到另一个ICollection,因为Select产生一个IEnumerable,这使得映射回属性到EF之后很痛苦,因为我必须重新创建集合或枚举它来更新它。我知道我错过了一些明显的东西,我已经更新了ICollection的是虚拟的概述在其他答案,但它是不清楚我如何帮助。

任何帮助都将非常感激!

杰拉德

将EF实体映射到视图模型,维护集合和延迟加载

假设您的".ToList()"问题是在保存回数据库时,这是您正在寻找的吗?:

 var event = new SS.Entity.Event {Name = "New Name" and other properties};
 IEnumerable<SS.Entity.User> broadcasters = e.Broadcasters
        .Select(u => new SS.Entity.User
             {
              Id = u.Id,
              SkypeId = u.SkypeId,
              Name = u.Name
           });
 var viewers = e.Viewers.Select(u =>
          new SS.Entity.User
          {
             Id = u.Id,
             SkypeId = u.SkypeId,
              Name = u.Name
          });
 //add broadcasters to event
 event.Broadcasters.AddRange(broadcasters);
 //add viewers to event
 event.Viewers.AddRange(viewers);
 dataContext.Events.Add(event);
 dataContext.SaveChanges();

在您的ViewModel上,它们可以只是IEnumerable<T>,除非您需要稍后对它们进行.Add()。你想做什么都行。此外,它们不必在模型上是虚拟的,因为您没有让EF创建模型的派生类型(再次强调,除非您有其他理由)。

将它们设置回它们在DTO对象中的状态,如果您只想直接设置它而不检查单个属性,您可以使用.ToList()使其满足ICollection<T>要求。

// Assuming "var model" is coming in as a parameter
var station = context.Viewers.First();
station.Broadcasters = model.Broadcasters.Select(b => new User {
    Id = b.Id,
    SkypeId = b.SkypeId,
    Name = b.Name
}).ToList();
station.Viewers = model.Viewers.Select(v => new User {
    Id = v.Id,
    SkypeId = v.SkypeId,
    Name = v.Name
});