C# 通过DTO集合检测模型集合中的更改

C# 通过DTO集合检测模型集合中的更改,c#,entity-framework,C#,Entity Framework,我收集了一些模型: class Person { public int Id {get;set;} public int Age {get;set;} public string Name {get;set;} } var collectionModel = new List<Person>{ ... }; 班级人员 { 公共int Id{get;set;} 公共整数{get;set;} 公共字符串名称{get;set;} } var collection

我收集了一些模型:

class Person
{
    public int Id {get;set;}
    public int Age {get;set;}
    public string Name {get;set;}
}

var collectionModel = new List<Person>{ ... };
班级人员
{
公共int Id{get;set;}
公共整数{get;set;}
公共字符串名称{get;set;}
}
var collectionModel=新列表{…};
和DTO的收集:

class PersonDto
{
    public int Id {get;set;}
    public int Age {get;set;}
    public string Name {get;set;}
    public int RowNumber {get;set;}
}

var collectionDto = new List<PersonDto>{ ... };
class PersonDto
{
公共int Id{get;set;}
公共整数{get;set;}
公共字符串名称{get;set;}
公共整数行号{get;set;}
}
var collectionDto=新列表{…};
所以,
collectionModel
我从存储库(数据库)获取,
collectionDto
我从远程客户端获取

是否有一种有效的方法来比较这些集合并在
collectionModel
上“应用更改”(更新更改的实体、删除不存在的实体和添加新的实体)以将其保存在数据库中


一个明显的选项是“手动”比较集合、更新属性、创建和删除对象。但是这个代码会重复。

不,没有。如果希望避免手动映射属性,可以将Person作为DTO传递,然后将其附加到实体框架上下文。在您的存储库中:

protected virtual void Merge(object modified, object attached)
{
    if (attached != modified)
        DB.Entry(attached).CurrentValues.SetValues(modified);
    else
        DB.Entry(modified).State = EntityState.Modified;
}
然后在插入或更新时:

public void UpdateSomething(Something obj)
{
    var attached = DB.Somethings.Single(x => x.ID == obj.ID);

    Merge(obj, attached);
    DB.SaveChanges();
}

对于更新的实体,您可以编写一个IEqualityComparer,将您的db对象与DTO进行比较,然后将需要发送回db的对象列表作为
EntitiyState.Modified
。添加和删除应该很简单(添加没有主ID,删除应该标记为删除)。@Wurd谢谢,但这正是我说的“手动”的意思。如果您关心映射,那么您可以查看AutoMapper。如果属性名称匹配,这将使模型和DTO之间的转换成为一行代码。:)但正如下面的回答,对于db逻辑,您必须投入一些精力。不确定您是否可以在某处找到“开箱即用”的功能。。。创建自己的类来完成它,这并不难。使用automapper和iQualityComparer。看看图书馆。@Wurd我们现在有类似的东西,我试着找到所有可能的选项。无论如何,谢谢你的意见,这将帮助我做出决定谢谢你的回答,我会考虑这个问题option@Backs在“合并”中,附着的对象是否应为相同类型的实体?这里它的1是dto,另一个是实体model@Eldho起初我得到DTO,但我可以在模型中转换它们