2016-02-02 75 views
0

我自己寫了一個庫來幫助進行通用數據庫查找。當我使用它時,我得到一個空白所有屬性的類。但是,基類正確填充。 product變量已正確填充。如何讓代碼填充派生類(TModel entity)?當我在DataService的Create方法設置斷點(內部代碼註釋),這些都是在當地人結果/汽車窗口:基類填充而不是子

public abstract class GenericLookupViewModel 
{ 
    [Key] 
    public int ID { get; set; } 

    [Required] 
    [StringLength(300)] 
    public string Name { get; set; } 

    [Required] 
    public bool Active { get; set; } 

    [StringLength(50)] 
    [DisplayName("Record last modified by")] 
    public string ModifiedBy { get; set; } 

    [DisplayName("Record last modified Date")] 
    [DataType(DataType.Date)] 
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)] 
    public DateTime ModifiedOn { get; set; } 

    [StringLength(50)] 
    [DisplayName("Record created by")] 
    public string CreatedBy { get; set; } 

    [DisplayName("Record creation Date")] 
    [DataType(DataType.Date)] 
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)] 
    public DateTime CreatedOn { get; set; } 

} 

的TModel:基於GenericLookupViewModel類

Autos Window

public class GenericLookupModelDataService<TModel, TViewModel> : object, IDisposable 
    where TModel : GenericLookupModel, new() 
    where TViewModel : GenericLookupViewModel, new() 



public virtual void Create(TViewModel product, string username = "SYSTEM") 
    { 
     TModel entity = new TModel 
     { 
      is_active = product.Active, 
      value = product.Name, 
      created_on = product.CreatedOn, 
      created_by = product.CreatedBy, 
      modified_on = product.ModifiedOn, 
      modified_by = product.ModifiedBy 
     }; 

     if (string.IsNullOrEmpty(entity.created_by)) //breakpoint here 
      entity.SetCreated(username); 
     if (string.IsNullOrEmpty(entity.modified_by)) 
      entity.SetModified(username); 

     _db.Set<TModel>().Add(entity); 
     _db.SaveChanges(); 
    } 

TViewModel基於GenericLookupModel類:

public abstract class GenericLookupModel : IActive, ICreated, IModified, IIdentity, IStringValue 
{ 
    public bool is_active { get; set; } 
    public string value { get; set; } 
    public DateTime created_on { get; set; } 
    public string created_by { get; set; } 
    public DateTime modified_on { get; set; } 
    public string modified_by { get; set; } 
    public int id {get;set;} 

    public void SetCreated(string creator = "SYSTEM") 
    { 
     created_by = creator; 
     created_on = DateTime.Now; 
    } 

    public void SetModified(string modifier = "SYSTEM") 
    { 
     modified_by = modifier; 
     modified_on = DateTime.Now; 
    } 

    public void ToggleActive() 
    { 
     is_active = !is_active; 
    } 

} 

控制器和行動:

public class PrimaryFocusController : GenericLookupViewModelController<PrimaryFocusViewModel,tblkp_PrimaryFocus> 
{ 
    public override ActionResult Create(PrimaryFocusViewModel lookup) 
    { 
     SetBrowsingUser(AppUser.Login); 
     return base.Create(lookup); 
    } 
} 

我編譯時得到警告可能必須做這樣的東西的信息庫:

warning CS0108: 'DataLayer.tblkp_PrimaryFocus.id' hides inherited member 'MyLib.Model.GenericLookupModel.id'. Use the new keyword if hiding was intended. warning CS0108: 'DataLayer.tblkp_PrimaryFocus.value' hides inherited member 'MyLib.Model.GenericLookupModel.value'. Use the new keyword if hiding was intended. warning CS0108: 'DataLayer.tblkp_PrimaryFocus.is_active' hides inherited member 'MyLib.Model.GenericLookupModel.is_active'. Use the new keyword if hiding was intended. warning CS0108: 'DataLayer.tblkp_PrimaryFocus.created_on' hides inherited member 'MyLib.Model.GenericLookupModel.created_on'. Use the new keyword if hiding was intended. warning CS0108: 'DataLayer.tblkp_PrimaryFocus.created_by' hides inherited member 'MyLib.Model.GenericLookupModel.created_by'. Use the new keyword if hiding was intended. warning CS0108: 'DataLayer.tblkp_PrimaryFocus.modified_on' hides inherited member 'MyLib.Model.GenericLookupModel.modified_on'. Use the new keyword if hiding was intended. warning CS0108: 'DataLayer.tblkp_PrimaryFocus.modified_by' hides inherited member 'MyLib.Model.GenericLookupModel.modified_by'. Use the new keyword if hiding was intended.

的DataLayer.tblkp_PrimaryFocus是EF生成的類使用DB First方法。

UPDATE:用戶@ code4life帶來了一個好點的 - 有標記爲virtual(tblkp_PrimaryFocus)子類的所有屬性,但是這將意味着,我需要以紀念所有的人每次重新生成模型從EF圖 - 這就是我想要避免的 - 修改EF生成的類。

+0

您需要將您想要在子類中重寫的屬性標記爲「虛擬」... – code4life

+0

問題是子類是由Entity Framework動態生成的。如果我開始修改這些模型,那麼每次從EF圖生成模型時都需要修改它們,我想避免這種情況。 –

回答

0

您可以修改T4模板(.tt文件)以將它們標記爲重寫或新的視情況。當然,基本類型的屬性必須標記爲虛擬。

我相信重寫會起作用,因爲您觀察到的行爲似乎是由於您的Create方法無法訪問繼承的屬性(它只具有基礎的定義,而且它們不是虛擬的)。這就是說,沒有太深入你的設計,我想這不完全是你想要的。

你真的想要的是防止代碼生成器發佈派生類的屬性開始,以便所有調用者使用基本定義。我建議你先看看T4模板,看看你是否不能添加匹配你的基類型屬性的規則。或者,考慮自定義屬性以匹配它們。

感覺好像有一種解決這個問題的通用方法,所以如果你能確認(我沒有太多考慮過),請考慮爲EF團隊編寫一份報告。

但是,期望建議切換到Code-First方法。坦率地說,我很想親自推薦給你。

+0

我認爲每次我將模型從.edmx文件中重新生成.tt模板也將被覆蓋 –

+0

@AdrianK。我鼓勵你去嘗試一下;我現在沒有任何參考資料,但我記得它並非如此。實際上,(C#)模型再生只是「重新運行模板」。只要你繼續使用相同的EDMX的東西應該按預期工作。 – tne