C# 递归反射:EF 模型到 Viewmodel(深)> 属性 未找到设置方法
C# recursive reflection : EF Model to Viewmodel (Deep) > Property set method not found
当我尝试设置 child Class 的属性时,我收到此错误:
附加信息: Property set method not found.
任何人都可以阐明这一点吗? - 很明显他们有二传手,见下面的 img
Class是:
public class Test
{
public string Name {get;set}
public LetterGrade Grade {get;set;}
}
pulic class LetterGrade
{
public string Name {get;set;}
public double GradePercentage {Get;set;}
}
使用:
var dbModel = context.Test.FirstOrDefault(w=>w.ID == ID)
this.Bind(dbModel);
这是我一直在调用 children(很好)但宁愿只进行 1 次调用(递归) 一些更复杂的objects会有children之children等等
this.LetterGrade.Bind(dbModel.LetterGrade);
是的,从技术上讲,您的问题是您试图将 PropertyInfo
类型的对象绑定到另一个相同类型的对象。
此外,您在这里尝试做什么不是很清楚 - 如果源 属性 值为空,您正试图将它的值绑定到目标 属性,这不应该发生。
代码可能应该重新安排,具体取决于您要实现的具体行为:引用类型的深度复制、简单引用复制、如何处理集合等...
我稍微修改了代码以展示这个想法:
public static void Bind(this object destination, object source)
{
if (source != null)
{
var destProperties = destination.GetType().GetProperties();
foreach (var sourceProperty in source.GetType().GetProperties())
{
var availableDestinationProperties = destProperties.Where(x=>x.Name == sourceProperty.Name && x.PropertyType.IsAssignableFrom(sourceProperty.PropertyType));
if (availableDestinationProperties.Count() == 0)
{
continue;
}
var destProperty = availableDestinationProperties.Single();
var sourcePropertyValue = sourceProperty.GetValue(source, null);
var destPropertyType = destProperty.PropertyType;
if (sourcePropertyValue != null)
{
if (IsCollection(destPropertyType))
{
//handle collections: either do collection item references copy, do deep copy of each element in collection, etc..
}
if (IsReferenceType(destPropertyType))
{
//do deep copy with recursion: create object OR do reference copy in case you need this
}
destProperty.SetValue(destination, sourcePropertyValue, new object[] { });
}
}
}
}
随着时间的推移,这些条件的数量会增加,您将不得不进行大量测试以验证一切正常。
如果您编写中小型应用程序,您仍然可以使用 AutoMapper,它并没有那么慢。如果您不特别喜欢它,还有其他第三方库可以做到这一点 - 您可以看到这样的问题,例如:Alternatives to AutoMapper
看来不值得你重新发明轮子
当我尝试设置 child Class 的属性时,我收到此错误:
附加信息: Property set method not found.
任何人都可以阐明这一点吗? - 很明显他们有二传手,见下面的 img
Class是:
public class Test
{
public string Name {get;set}
public LetterGrade Grade {get;set;}
}
pulic class LetterGrade
{
public string Name {get;set;}
public double GradePercentage {Get;set;}
}
使用:
var dbModel = context.Test.FirstOrDefault(w=>w.ID == ID)
this.Bind(dbModel);
这是我一直在调用 children(很好)但宁愿只进行 1 次调用(递归) 一些更复杂的objects会有children之children等等
this.LetterGrade.Bind(dbModel.LetterGrade);
是的,从技术上讲,您的问题是您试图将 PropertyInfo
类型的对象绑定到另一个相同类型的对象。
此外,您在这里尝试做什么不是很清楚 - 如果源 属性 值为空,您正试图将它的值绑定到目标 属性,这不应该发生。
代码可能应该重新安排,具体取决于您要实现的具体行为:引用类型的深度复制、简单引用复制、如何处理集合等...
我稍微修改了代码以展示这个想法:
public static void Bind(this object destination, object source)
{
if (source != null)
{
var destProperties = destination.GetType().GetProperties();
foreach (var sourceProperty in source.GetType().GetProperties())
{
var availableDestinationProperties = destProperties.Where(x=>x.Name == sourceProperty.Name && x.PropertyType.IsAssignableFrom(sourceProperty.PropertyType));
if (availableDestinationProperties.Count() == 0)
{
continue;
}
var destProperty = availableDestinationProperties.Single();
var sourcePropertyValue = sourceProperty.GetValue(source, null);
var destPropertyType = destProperty.PropertyType;
if (sourcePropertyValue != null)
{
if (IsCollection(destPropertyType))
{
//handle collections: either do collection item references copy, do deep copy of each element in collection, etc..
}
if (IsReferenceType(destPropertyType))
{
//do deep copy with recursion: create object OR do reference copy in case you need this
}
destProperty.SetValue(destination, sourcePropertyValue, new object[] { });
}
}
}
}
随着时间的推移,这些条件的数量会增加,您将不得不进行大量测试以验证一切正常。
如果您编写中小型应用程序,您仍然可以使用 AutoMapper,它并没有那么慢。如果您不特别喜欢它,还有其他第三方库可以做到这一点 - 您可以看到这样的问题,例如:Alternatives to AutoMapper
看来不值得你重新发明轮子