Jam*_*mes 4 .net c# comparison performance entity-framework
可能重复:
比较两个实体框架实体的最佳方法是什么?
我想知道比较两个相同类型实体的最有效方法。
一个实体是通过xml文件手动创建的(即,新实例和手动设置的属性),而另一个则是从我的对象上下文中删除的。
我想知道每个实例中的属性值是否相同。
我的第一个想法是从每个对象生成属性值的哈希值并比较哈希值,但是可能有另一种方法还是内置方法?
欢迎大家提出意见。
非常感谢,
詹姆士
更新
我想出了这个:
static class ObjectComparator<T>
{
static bool CompareProperties(T newObject, T oldObject)
{
if (newObject.GetType().GetProperties().Length != oldObject.GetType().GetProperties().Length)
{
return false;
}
else
{
var oldProperties = oldObject.GetType().GetProperties();
foreach (PropertyInfo newProperty in newObject.GetType().GetProperties())
{
try
{
PropertyInfo oldProperty = oldProperties.Single<PropertyInfo>(pi => pi.Name == newProperty.Name);
if (newProperty.GetValue(newObject, null) != oldProperty.GetValue(oldObject, null))
{
return false;
}
}
catch
{
return false;
}
}
return true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我还没有测试过,它更是一种思想,可以从小组中产生更多的想法。
可能存在问题的一件事是比较本身具有实体值的属性,如果默认比较器根据对象引用进行比较,那么它将永远不会成立。一种可能的解决方法是使相等运算符重载到我的实体上,以便对实体ID进行比较。
照原样,代码将无法满足您的期望。
试试这个简单的测试:
class A {
public int Id { get; set; }
public string Name { get; set; }
}
class B : A {
public DateTime BirthDate { get; set; }
}
class ObjectComparer {
public static void Show() {
A a = new A();
B b = new B();
A a1 = new A();
Console.WriteLine(ObjectComparator.CompareProperties(a, b));
Console.WriteLine(ObjectComparator.CompareProperties(b, a));
Console.WriteLine(ObjectComparator.CompareProperties(a, a1));
}
}
Run Code Online (Sandbox Code Playgroud)
您会期望它返回
假
假
真正
但它返回
假
假
假
尝试更改内部外观,例如:
if (!object.Equals(newProperty.GetValue(newObject, null), oldProperty.GetValue(oldObject, null))) {
return false;
}
Run Code Online (Sandbox Code Playgroud)
如果a和a1都引用同一对象,则还可以节省一些时间,方法是在方法开始时进行检查。
static class ObjectComparator {
public static bool CompareProperties(T newObject, T oldObject) {
if (object.Equals(newObject, oldObject)) {
return true;
}
if (newObject.GetType().GetProperties().Length != oldObject.GetType().GetProperties().Length) {
return false;
}
else {
var oldProperties = oldObject.GetType().GetProperties();
foreach (PropertyInfo newProperty in newObject.GetType().GetProperties()) {
try {
PropertyInfo oldProperty = oldProperties.Single(pi => pi.Name == newProperty.Name);
if (!object.Equals(newProperty.GetValue(newObject, null), oldProperty.GetValue(oldObject, null))) {
return false;
}
}
catch {
return false;
}
}
return true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您对性能感到满意,则可以在方法的生存期内将Type.GetProperties的返回结果缓存到局部变量中,因为反射至少在3.5 SP1版本之前不会自行执行。这样,您会将GetProperties调用从四个降至两个。
如果只希望比较完全相同类型的对象(或者换一种方式不比较基本实例和派生实例),则可以进一步将GetProperties的调用减少到一个。
希望这可以帮助。
归档时间: |
|
查看次数: |
11381 次 |
最近记录: |