虚拟 属性 上的属性未通过反射显示

attribute on virtual property not showing via reflection

我有一个带有属性的 EntityFramework 模型,我用它来验证字段。

private person tipProvider;
[Required]
[ForeignKey("TipProviderId")]
public virtual person TipProvider
{
    get { return tipProvider; }
    set
    {
        tipProvider = value;
        ValidateProperty(MethodBase.GetCurrentMethod().Name.Replace("set_", ""));
        raisePropertyChanged(MethodBase.GetCurrentMethod().Name.Replace("set_", ""));
    }
}

我得到 PropertyInfo 然后是它的验证属性,我用它来验证 属性:

public virtual void ValidateProperty(string property)
{
    errors[property].Clear();
    var propertyInfo = this.GetType().GetProperty(property);
    var propertyValue = propertyInfo.GetValue(this);
    var validationAttributes = propertyInfo.GetCustomAttributes(true).OfType<ValidationAttribute>();
    foreach (var validationAttribute in validationAttributes)
    {
        if (!validationAttribute.IsValid(propertyValue))
        {
            errors[property].Add(validationAttribute.FormatErrorMessage(string.Empty));
        }
    }
    raiseErrorsChanged(property);
}

当属性是虚拟的时候,我无法通过反射找到属性。如果删除 virtual 关键字,则会找到属性。

我真的被这种行为搞糊涂了。为什么属性不能应用于虚拟属性?

我不知道你究竟想做什么,但据我从EntityFramework了解到的情况,问题并不完全是你想的那样。您可以将属性应用于虚拟属性,并且可以通过反射毫无问题地恢复它们,就像您正在做的那样。

但是在 EF 实体上,当您将 属性 标记为虚拟时,您是在向 EF 定义 属性 是一个导航 属性(一个 属性 用于访问关系中的外键数据,并将其作为子实体检索)。

然后,当您在运行时从数据库上下文中获取此实体的新实例并访问该 属性 时,EF 将创建一个新的 class(动态代理),它源自您的 class 并使用它代替原来的 class。 Entity Framework 这样做是为了维护 "Lazy Loading" 你的关系的概念 - 避免在不需要的情况下加载整个新的依赖实体树。

因为 EF 从您的实体创建了一个新的 class,并且 属性 被它覆盖,您的属性没有被它继承。

您可以在 this post 上查看有关虚拟标记和导航属性的更多信息。