比较 .NET 中的两个模型

本文关键字:两个 模型 NET 比较 | 更新日期: 2023-09-27 18:18:51

让我们对我们有的模型进行成像:

public class InheritModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string OtherData { get; set; }
}

我们有一个带有视图的控制器,它代表这个模型:

private InheritModel GetAll()
{
    return new InheritModel
    {
        Name = "name1",
        Description = "decs 1",
        OtherData = "other"
    };
}
public ActionResult Index()
{
    return View(GetAll());
}

现在我们可以在视图中编辑它,更改一些数据并发布回服务器:

[HttpPost]
public ActionResult Index(InheritModel model)
{
    var merged = new MergeModel();
    return View(merged.Merge(model, GetAll()));
}

我需要做什么:

  • 鉴于我们有模型的复制
  • 用户更改某些内容并发布
  • 合并方法需要逐字段比较已发布的模型和以前的模型
  • 合并方法使用在发布模型中更改的数据创建新的继承模型,所有其他数据都应为 null

有人可以帮我制作这个合并方法吗?

更新(!

这不是一项微不足道的任务。接近像:

public InheritModel Merge(InheritModel current, InheritModel orig)
{
    var result = new InheritModel();
    if (current.Id != orig.Id) 
    {
        result.Id = current.Id;
    }
}

不適用。它应该是通用解决方案。我们在模型中有 200 多个属性。第一个模型是从DB的severeal表构建的。

比较 .NET 中的两个模型

public InheritModel Merge(InheritModel current, InheritModel orig)
{
    var result = new InheritModel();
    if (current.Id != orig.Id) 
    {
        result.Id = current.Id;
    }
    if (current.Name != orig.Name) 
    {
        result.Name = current.Name;
    }
    ... for the other properties
    return result;
}

另一种可能性是使用反射并遍历所有属性并设置其值:

public InheritModel Merge(InheritModel current, InheritModel orig)
{
    var result = new InheritModel();
    var properties = TypeDescriptor.GetProperties(typeof(InheritModel));
    foreach (PropertyDescriptor property in properties)
    {
        var currentValue = property.GetValue(current);
        if (currentValue != property.GetValue(orig))
        {
            property.SetValue(result, currentValue);
        }
    }
    return result;
}

显然,这仅适用于 1 级属性嵌套。

每个主题,似乎您想要的是一种"更改跟踪"机制,无论如何都绝对不是微不足道或简单的。也许,使用任何现代ORM解决方案来为您做到这一点是有意义的,不是吗?

因为否则,您需要开发维护"上下文"(第一级对象缓存(的东西,例如 EF 的 ObjectContext 或 NH 的 Session,这将是通用解决方案。

此外,没有关于较低级别发生的情况的信息 - 您如何实际保存数据。您是否已经有一些机制可以通过遍历对象的"非 null"属性来保存对象?

我有类似的项目经验,这让我对原始设计思考了很多。思考以下问题:

您有一个视图,该视图表示模型,然后修改了用户 视图中模型的某些内容,所有更改都发布到 服务器和模型被修改,然后将其保存到数据库 可能。什么发布到地球上的服务器?

InheritModel的实例?不。您只需要更改。它实际上是InheritModel的一部分,它是一个InheritModel Updater,它是Updater<InheritModel>的一个实例。在您的问题中,您需要合并两个模型,因为您的Update方法如下所示:

public InheritModel Update(InheritedModel newModel)
{
    //assign the properties of the newModel to the old, and save it to db
    //return the latest version of the InheritedModel
}

现在问问自己:当我只想更新一个属性时,为什么我需要整个InheritedModel实例?

所以我的最终解决方案是:将更改发布到控制器,参数类似于Updater<TModel>,而不是TModel本身。并且Updater<TModel>可以应用于TModel,更新程序中指定的属性被分配并保存。不应该有合并操作。