【问题标题】:C# recursive reflection : EF Model to Viewmodel (Deep) > Property set method not foundC# 递归反射:EF 模型到 Viewmodel(深度)> 找不到属性集方法
【发布时间】:2016-05-27 08:03:02
【问题描述】:

当我尝试设置子类的属性时,我收到此错误:

其他信息: Property set method not found.

任何人都可以对此有所了解吗? - 显然他们有二传手,见下面的图片

类:

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);

这就是我一直在调用孩子的方式(很好)但宁愿只进行 1 次调用(递归) 一些更复杂的对象会有孩子的孩子等等

this.LetterGrade.Bind(dbModel.LetterGrade); 

【问题讨论】:

  • 是否引发异常的属性有setter?
  • 你为什么不使用像 AutoMapper 这样的库呢?
  • @raderick 我听说自动映射器在将副本 1 对象移动到另一个对象的开销方面有点慢。
  • @haim770 从我所看到的,从这段代码来看,没有。但是,我的主类上的一个属性是否作为目标传递给上述函数并且它们的属性是公共的?我将在一些类中进行编辑以供参考。
  • 嗯,在您的通用代码中,您不应该将属性绑定到属性 (destProperty.Bind(sourceProperty)),而是将两个属性的值相互映射,如果它为空,则创建对象的新实例目的地财产。或者您应该使用属性值而不进行深度复制,具体取决于您尝试实现的逻辑。

标签: c# entity-framework recursion reflection viewmodel


【解决方案1】:

是的,从技术上讲,您的问题是您试图将PropertyInfo 类型的对象绑定到另一个相同类型的对象。

此外,您在这里尝试做什么也不是很清楚 - 如果源属性值为 null,则您正在尝试将其值绑定到目标属性,这不应该发生。

代码可能应该重新排列,并取决于您具体尝试实现的行为:引用类型的深层副本、简单引用副本、如何处理集合等...

我稍微修改了代码以显示这个想法:

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,它并没有那么慢。如果你不特别喜欢它,还有其他 3rd 方库可以做到这一点 - 你可以看到这样的问题,例如:Alternatives to AutoMapper

看来你不值得重新发明轮子。

【讨论】:

  • null 不复制是设计使然,因为它被复制到的位置始终是具有相同属性的新对象,因此已经为 null。非常感谢替代页面 - 我已经完成并爱上了价值注入器的使用。 (这就是我的目标)
猜你喜欢
  • 2011-02-11
  • 1970-01-01
  • 1970-01-01
  • 2016-02-08
  • 2016-06-14
  • 2016-01-24
  • 1970-01-01
  • 2017-09-04
  • 2011-05-02
相关资源
最近更新 更多