2009-01-19 33 views
16

生成的代碼特性副屬性我想在.NET公共屬性設置的屬性,但是我沒有獲得明確的財產本身,因爲這已經在另一個文件中生成的代碼。在.NET

我有這樣的領域:

public virtual string Name { get; set; } 

我想設置此:

[ValidateNonEmpty("Name is required", ExecutionOrder = 1)] 
public virtual string Name { get; set; } 

我的類被標記爲局部的,但你不能有部分物業。我以爲我到的東西與MetadataType類是動態數據和DataAnnotations的一項新功能,但很可惜,我覺得它只能與動態數據使用的,這是真的嗎?

引文: http://blogs.oosterkamp.nl/blogs/jowen/archive/2008/10/16/metadatatype-attribute.aspx http://blogs.msdn.com/davidebb/archive/2008/06/16/dynamic-data-and-the-associated-metadata-class.aspx

有什麼辦法,我可以設置該屬性(甚至通過web.config中!)不接觸生成的代碼的類?

由於提前, 格雷厄姆

回答

22

這是一個已知滋擾;你根本無法將元數據添加到生成的成員。

這裏有6個選項(爲了提高工作的):

  • 如果你自己的屬性,使其可以聲明其對類,例如:[ValidateNonEmpty("Name", "Name is required", ExecutionOrder = 1)] - 再加入多個屬性的部分類定義
  • 使用虛擬/接口/ etc方法來查詢這個,而不是通過屬性
  • 子類生成的類型;覆蓋或重新申報的成員,加入了元數據(真的很亂)
  • 使用自定義TypeDescriptionProvider提供動態的元數據(很多很多的工作) - 假設消費者方面TypeDescriptor;多數結合相關的消費者做的,但例如,Expression(由許多LINQ提供程序使用)不
  • 變化的代碼生成器/寫自己的
  • 儘量延長像PostSharp做的工作(我的天堂「T找到了一個辦法做到這一點,但我愛聽到的話,你想辦法!)

我通常與第一種選擇成功,除非它是一個系統定義的屬性([DisplayName]等)。如果[ValidateNonEmpty]由動態數據定義,那麼您可能無法做到這一點。

+0

感謝馬克, 我想這可能是這種情況。我設法遍歷了我的「MetadataType」聲明類的屬性,我希望查詢這些屬性,並簡單地將「meta」屬性的名稱與真實屬性進行比較。 – GONeale 2009-01-19 06:14:07

+0

我明白,這與查詢真實屬性是不一樣的,但是對於我所需要的,它看起來會在這種情況下起作用。這很棒。 – GONeale 2009-01-19 06:14:38

1

另一種選擇是包裹在同一類內的非生成的屬性的屬性。不理想,因爲你最終可能擁有雙重屬性,但如果你可以讓你的發電機做出保護屬性,這將是一個很好的方法。

就不得不面對這個問題:實體框架生成的類,我想將它們序列化JSON用更簡單的名稱。

// GENERATED BY EF 
public partial class ti_Users 
{ 
    public ti_Users() 
    { 
     this.ti_CardData = new HashSet<ti_CardData>(); 
     this.ti_Orders = new HashSet<ti_Orders>(); 
    } 

    protected int userId { get; set; } 
    protected string userName { get; set; } 
    protected string userEmail { get; set; } 
    protected string userPassHash { get; set; } 
    protected Nullable<System.DateTime> userLastLogin { get; set; } 
    protected string userLastIP { get; set; } 

    public virtual ICollection<ti_CardData> ti_CardData { get; set; } 
    public virtual ICollection<ti_Orders> ti_Orders { get; set; } 
} 

和附加類:

[JsonObject(memberSerialization: MemberSerialization.OptIn)] 
public partial class ti_Users 
{ 
    [JsonProperty] 
    public int UserId 
    { 
     get { return this.userId; } 
     set { this.userId = value; } 
    } 

    [JsonProperty] 
    public string Name 
    { 
     get { return this.userName; } 
     set { this.userName = value; } 
    } 

    [JsonProperty] 
    public string Email 
    { 
     get { return this.userEmail; } 
     set { this.userEmail = value; } 
    } 

    [JsonProperty] 
    public string PassHash 
    { 
     get { return this.userPassHash; } 
     set { this.userPassHash = value; } 
    } 
} 
6

由於生成的類是局部類,下面應該工作:

  1. 創建具有這個屬性中聲明的接口它,並用ValidateNonEmpty屬性裝飾它。
  2. 創建具有相同的名稱自動生成的類自己的部分類,並讓這個工具,你剛剛創建的接口。

    // Decorate the properties with attributes as required 
    public interface IMyInterface 
    { 
        [ValidateNonEmpty("Name is required")] 
        string Name { get; set; } 
    } 
    
    // This is the partial class I created, that implements the interface 
    public partial class MyGeneratedClass : IMyInterface 
    {  
    } 
    
    // This is the auto-generated class 
    public partial class MyGeneratedClass 
    { 
        public virtual string Name { get; set; } 
    } 
    

    我有這個想法從geekswithblogs

  3. 屬性現在應該與屬性

例如裝飾。

2

這是一個很好的解決方案,但它並沒有對我的問題的工作。我使用EF 6和現有數據庫中的代碼優先生成的類。表中的一列是具有自動生成值的IDENTITY。但是,生成的部分類沒有提供使數據庫生成密鑰所需的屬性數據集。結果是錯誤「當IDENTITY_INSERT設置爲OFF時,無法在表'mytable'中爲標識列插入顯式值。」。我試過你的解決方案,但它沒有奏效。但是,如果我將該屬性添加到原始生成的類,它確實有效。所以我仍然試圖找到一個不需要修改自動生成文件的解決方案。

下面是我用你的解決方案試圖代碼:

public interface IMyTable 
{ 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    int ID { get; set; } 
} 

public partial class MyTable : IMyTable 
{ 
} 

原生成的代碼:

[Table("MyTable")] 
public partial class MyTable 
{ 
    [Key] 
    [Column(Order = 1)] 
    public int ID { get; set; } 
}