使用POCO实体框架4时丢失DataAnnotations

时间:2011-11-14 17:34:39

标签: asp.net-mvc-3 entity-framework-4 entity-framework-4.1 data-annotations poco

我正在将新的EntityFramework 4.1与POCO对象一起使用,并与DataAnnotation框架结合使用。

当EntityFramework需要创建代理类(例如,延迟加载虚拟属性)时,我的所有数据注释都将丢失。有没有什么方法可以让我的ModelMetaData来自代理的类,而不是代理类?

我知道我可以选择禁用代理创建(context.Configuration.ProxyCreationEnabled),但这似乎是一个糟糕的答案。我认为这应该是已经解决的问题。

以下是一些示例代码:

public class Person
{
    [Required, Display(Name = "Display That Name")]
    public string DisplayName { get; set; }
}

然后在视图中的模型元数据中,类型为:Person_9C92B92D56F6F4F0FB1686526D585438A05323CC72E457C2152796E8866297E1 (FullName = "System.Data.Entity.DynamicProxies.Person_9C92B92D56F6F4F0FB1686526D585438A05323CC72E457C2152796E8866297E1"}),我的元数据消失了,显示名称在“DisplayName”处呈现,而不是“显示该名称”。

有什么建议吗?

3 个答案:

答案 0 :(得分:6)

您可以制作模型类的元数据版本。 我们这样做...... EF产生的东西永远不会被手触摸。

我们说你有一个Person类:

public partial class Person
{
        public int idPerson { get; set; }
        public int idTenant { get; set; }
        public string Name { get; set; }
}

然后你可以创建元数据类,它保存元数据并且不会被覆盖:

[MetadataType(typeof(PersonMD))]
    public partial class Person
    {
       //leave it empty
    }

    public partial class PersonMD
    {
       [Required]
       public int idPerson { get; set; }

       [Required]
       public int idTenant { get; set; }

       [Required, Display(Name = "Display That Name")]
       public string Name { get; set; }
    }

答案 1 :(得分:1)

我们的工作如下:

修改T4模板以为您的实体生成部分类。

对于您希望添加注释的实体,请创建与您的实体同名的部分类。

在此类中创建一个提供注释详细信息的好友类。

在部分类的顶部应用属性,以指定您的好友类是可以找到注释详细信息的位置。

有关详细信息,请参阅此处http://msdn.microsoft.com/en-us/library/ee256141.aspx

答案 2 :(得分:0)

我想出了一个可能的解决方案。不确定是否有更好的。首先,我写了一个新的ModelMetadataProvider:

public class IgnoreProxiesDataAnnotationsModelMetadataProvider : System.Web.Mvc.DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
    {
        modelType = ObjectContext.GetObjectType(modelType);
        containerType = ObjectContext.GetObjectType(containerType);

        return base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
    }
}

然后在Global.asax应用程序中注册它:

ModelMetadataProviders.Current = new IgnoreProxiesDataAnnotationsModelMetadataProvider();

如果有更好的解决方案,请告诉我们!