将数据注释添加到由entity framework生成的类

我有以下由entity framework生成的类:

public partial class ItemRequest { public int RequestId { get; set; } //... 

我想将此作为必填字段

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

但是,因为这是生成的代码,这将被消灭。 我无法想象创build一个部分类的方法,因为属性是由生成的部分类定义的。 我怎样才能以安全的方式定义约束?

生成的类ItemRequest将始终是一个ItemRequest类。 这使您可以编写第二个部分类,它标有必要的数据注释。 在你的情况下,部分类ItemRequest将如下所示:

 using System.ComponentModel; using System.ComponentModel.DataAnnotations; //make sure the namespace is equal to the other partial class ItemRequest namespace MvcApplication1.Models { [MetadataType(typeof(ItemRequestMetaData))] public partial class ItemRequest { } public class ItemRequestMetaData { [Required] public int RequestId {get;set;} //... } } 

正如MUG4N回答你可以使用部分类,但将更好地使用接口 。 在这种情况下,如果EF模型不符合validation模型,将会出现编译错误。 所以你可以修改你的EF模型而不用担心validation规则是过时的。

 using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace YourApplication.Models { public interface IEntityMetadata { [Required] Int32 Id { get; set; } } [MetadataType(typeof(IEntityMetadata))] public partial class Entity : IEntityMetadata { /* Id property has already existed in the mapped class */ } } 

PS如果您使用的是与ASP.NET MVC不同的项目types(当您执行手动数据validation时),请不要忘记注册您的validation器

 /* Global.asax or similar */ TypeDescriptor.AddProviderTransparent( new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Entity), typeof(IEntityMetadata)), typeof(Entity)); 

我find了一个类似于MUG4N的答案,而是将MetaData类嵌套在实体类中,从而减less了公共名称空间列表中的类的数量,并且不需要为每个元数据类指定唯一的名称。

 using System.ComponentModel.DataAnnotations; namespace MvcApplication1.Models { [MetadataType(typeof(ItemRequest.MetaData))] public partial class ItemRequest { internal class MetaData { [Required] public int RequestId {get;set;} //... } } } 

确保放置“。” 在typeof函数中。

这是@dimonser答案的扩展,如果你重新生成你的数据库模型,你将不得不手动重新添加这些类的接口。

如果你有它的胃口,你也可以修改你的.tt模板:

下面是一些类的自动生成接口的例子,这是.tt片段,只需用你的实体名称和接口显然是var stringsToMatchreplace你的EntityClassOpening方法。

 public string EntityClassOpening(EntityType entity) { var stringsToMatch = new Dictionary<string,string> { { "Answer", "IJourneyAnswer" }, { "Fee", "ILegalFee" } }; return string.Format( CultureInfo.InvariantCulture, "{0} {1}partial class {2}{3}{4}", Accessibility.ForType(entity), _code.SpaceAfter(_code.AbstractOption(entity)), _code.Escape(entity), _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)), stringsToMatch.Any(o => _code.Escape(entity).Contains(o.Key)) ? " : " + stringsToMatch.Single(o => _code.Escape(entity).Contains(o.Key)).Value : string.Empty); } 

虽然没有一个正常的人应该这样做,但是在圣经中已经certificate,这是为了这个。

我不知道如何去做你所要求的,但有一个办法。 通过覆盖自定义DataAnnotationsModelValidatorProvider的GetValidators进行dynamic数据validation。 在这里你可以阅读validation每个字段的规则(从数据库,configuration文件等),并添加validation器,如果需要的话。 它具有附加值,您的validation不再与模型紧密结合,可以在无需重新启动站点的情况下进行更改。 当然,这可能是你的情况矫枉过正,但它是我们的理想select!

修改添加所需注释的T4模板,这个文件通常命名为MODELNAME.tt

findT4在哪里创build类和方法知道在哪里把这些。

  <#=codeStringGenerator.IgnoreJson(navigationProperty)#> //create this method in file public string IgnoreJson(NavigationProperty navigationProperty){ string result = navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? "" : @"[JsonIgnore] [IgnoreDataMember]"; return result; } 

您还需要添加命名空间;

 <#=codeStringGenerator.UsingDirectives(inHeader: false)#> using System.ComponentModel.DataAnnotations; using Newtonsoft.Json; using System.Runtime.Serialization; 

通过保存你的模型来重build你的类,所有的方法都应该被注释掉。