【问题标题】:Losing DataAnnotations when using POCO Entity Framework 4使用 POCO Entity Framework 4 时丢失 DataAnnotations
【发布时间】:2011-12-28 20:45:16
【问题描述】:

我将新的 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”而不是“Display That Name”。

有什么建议吗?

【问题讨论】:

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


    【解决方案1】:

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

    假设你有一个 Person 类:

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

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

    [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; }
        }
    

    【讨论】:

      【解决方案2】:

      我们的做法如下:

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

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

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

      应用部分类顶部的属性来指定您的伙伴类是可以找到注释详细信息的位置。

      更多详情请看这里http://msdn.microsoft.com/en-us/library/ee256141.aspx

      【讨论】:

        【解决方案3】:

        我想出了一种可能的解决方案。不确定是否有更好的。首先我写了一个新的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();
        

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

        【讨论】:

        • 要确定一个类型是否被代理,它更容易使用 ObjectContext.GetObjectType。
        猜你喜欢
        • 2011-07-19
        • 2011-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多