是否可以比较两个模型并仅显示差异,例如已更新,添加或删除的内容?
例如,在以下模型中,我创建了多个Sample
模型:
var grocers1 = new List<Grocer>();
var grocer1 = new Grocer
{
Id = 1,
Expenditure = 500,
Name = "Bob"
};
grocers1.Add(grocer1);
var grocers2 = new List<Grocer>();
var grocer2 = new Grocer
{
Id = 1,
Expenditure = 300,
Name = "Bob"
};
grocers2.Add(grocer2);
var fruits = new List<Fruit>();
var fruit1 = new Fruit();
fruits.Add(fruit1);
var orders1 = new List<Order>();
var order1 = new Order
{
Id = 1,
SampleId = 1,
Fruits = fruits
};
var order2 = new Order
{
Id = 1,
SampleId = 1,
Fruits = fruits
};
orders1.Add(order1);
orders1.Add(order2);
var orders2 = new List<Models.Documents.Order> {order1};
var sample = new Sample
{
Id = 1,
Date = Convert.ToDateTime("2018-10-23"),
Grocers = grocers1,
Orders = orders1
};
var changedSample = new Sample
{
Id = 1,
Date = Convert.ToDateTime("2018-10-22"),
Grocers = grocers2,
Orders = orders1
};
var otherChangedSample = new Sample
{
Id = 1,
Date = Convert.ToDateTime("2018-10-23"),
Grocers = grocers1,
Orders = orders2
};
因此,如果我将sample
与changedSample
进行比较,它应该仅显示日期已从2018-10-23更改为2018-10-22,并且支出已从500更改为300。 / p>
然后,如果我将sample
与otherChangedSample
进行比较,则应该表明order2
已被删除。
最后,如果我将otherChangedSample
与sample
进行比较,则表明已经添加了2号订单。
我已经用AutoMapper测试过,这对于比较相同的基本模型(不包括列表)非常有用,它很好地突出了更改。
然后我尝试了Compare-Net-Objects,这很好,这一次确实考虑了列表并突出显示了更改,但前提是列表数量保持不变。它将识别列表计数的更改,但不会告诉您已删除的值或已添加的值。
任何帮助将不胜感激。
答案 0 :(得分:0)
您也可以使用反射和扩展方法:
var sample = new Sample
{
Id = 1,
Date = Convert.ToDateTime("2018-10-23"),
Grocers = grocers1,
Orders = orders1
};
var otherChangedSample = new Sample
{
Id = 1,
Date = Convert.ToDateTime("2018-10-23"),
Grocers = grocers1,
Orders = orders2
};
class Variance
{
public string Prop { get; set; }
public object valA { get; set; }
public object valB { get; set; }
}
List<Variance> rt = sample.DetailedCompare(otherChangedSample);
using System.Collections.Generic;
using System.Reflection;
static class extentions
{
public static List<Variance> DetailedCompare<T>(this T val1, T val2)
{
List<Variance> variances = new List<Variance>();
FieldInfo[] fi = val1.GetType().GetFields();
foreach (FieldInfo f in fi)
{
Variance v = new Variance();
v.Prop = f.Name;
v.valA = f.GetValue(val1);
v.valB = f.GetValue(val2);
if (!v.valA.Equals(v.valB))
variances.Add(v);
}
return variances;
}
}
答案 1 :(得分:0)
您是否自己编写了模型类代码?如果不是这样,则必须处理反射(速度可能很慢,并且必须进行很多编程才能覆盖所有数据类型),或者要处理序列化(序列化为字符串并进行字符串比较)。
如果您可以扩展您的类,那么我将为每个单独的类添加一个方法:
internal void TrackChange(T other, List<Change> changes)
您的课程Sampe
中的此方法如下:
void TrackChange(Sample other, List<Change> changes)
{
if (this.Id != other.Id) changes.add(new Change(...));
if (this.Date != other.Date) changes.add(new Change(...));
if (this.Grocers.count != other.Grocers.count) changes.add(new Change(...)); // number of items has changed
for (int i = 0; i < math.min(this.grocers.count, other.grocers.count); i++)
this.grocers[i].TrackChange(other.grocers[i], changes);
....
}
Grocer
类具有其自己的TrackChange方法。等等。
这是一些编码,但是效率最高,您可以自己处理所有情况。例如,如果您不介意列表中的杂货店顺序,则可以迭代此列表中的所有杂货店,并尝试在其他列表中找到对应的杂货店(例如,按ID),然后致电TrackChange。