[.NET][EF]設定MetaData Class來保留edmx的屬性

  • 747
  • 0
  • 2016-06-08

[.NET][EF]設定MetaData Class來保留edmx的屬性

以微軟的範例資料庫AdventureWorks為例,假設現在有個edmx自動產生的Contact類別如下,內容是由visual studio的ado.net entity model自動產生的:

//------------------------------------------------------------------------------
// <auto-generated>
//     這個程式碼是由範本產生。
//
//     對這個檔案進行手動變更可能導致您的應用程式產生未預期的行為。
//     如果重新產生程式碼,將會覆寫對這個檔案的手動變更。
// </auto-generated>
//------------------------------------------------------------------------------

namespace WebAPIOData.Models
{
    using System;
    using System.Collections.Generic;
    
    public partial class Contact
    {
        public Contact()
        {
            this.Employee = new HashSet<Employee>();
        }
    
        public int ContactID { get; set; }
        public bool NameStyle { get; set; }
        public string Title { get; set; }
        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        public string LastName { get; set; }
        public string Suffix { get; set; }
        public string EmailAddress { get; set; }
        public int EmailPromotion { get; set; }
        public string Phone { get; set; }
        public string PasswordHash { get; set; }
        public string PasswordSalt { get; set; }
        public string AdditionalContactInfo { get; set; }
        public System.Guid rowguid { get; set; }
        public System.DateTime ModifiedDate { get; set; }
    
        public virtual ICollection<Employee> Employee { get; set; }
    }
}

當每次重新從資料庫update之後,edmx的類別也都會被重新產出,因此無法從此自動產出的類別增加任何的屬性,這時候就可以利用MetaData Class,以下的寫法範例將

public virtual ICollection<Employee> Employee { get; set; }

這個欄位加上了屬性[JsonIgnore]:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

//name space要故意設定的跟原本的Contact.cs一樣,此MetaData Class才有效喔
namespace WebAPIOData.Models
{
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    [MetadataType(typeof(ContactMetadata))]
    public partial class Contact
    {
        private class ContactMetadata
        {
            [JsonIgnore]
            public virtual ICollection<Employee> Employee { get; set; }
			
			//[Display(Name="路徑名稱")]
            //public virtual string route_name { get; set; }
        }
    }
}

要注意的重點是,此MetaData Class可以加入在任何資料夾路徑下(不過當然不能跟edmx同路徑,不然會被visual studio拒絕),類別名稱也可以隨便你亂取,但是程式碼裡面的name space一定要取的跟自動產生的Contact.cs一模一樣才有效果喔。

測試結果:
沒有加入MetaData class的WebAPI, 由於Contact與Employee資料表互相為關連資料表,因此postman查詢contact這個資料表的時候,產生self loop reference無限自我循環的錯誤:

加入MetaData Class之後,就可以順利查詢此WebAPI的Contact資料表了:

本篇大概是這樣。。。

參考文章:
ASP.NET MVC 開發心得分享 (24):擴充部分類別的建構子