填充基类而不是子

时间:2016-02-02 12:58:55

标签: c# asp.net-mvc entity-framework generics

我自己写了一个库来帮助进行通用数据库查找。当我使用它时,我得到一个所有属性都空白的类。但是,基类已正确填充。 product变量已正确填充。我如何使代码填充派生类(TModel entity)?当我在dataservice Create方法中设置断点(代码内部注释)时,这些是Locals / Autos窗口中的结果:

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基于GenericLookupViewModel类:

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

}

基于GenericLookupModel类的TModel:

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是使用DB First方法从EF生成的类。

更新:用户@ code4life带来了一个好点 - 将子类的所有属性标记为virtual(tblkp_PrimaryFocus),但这意味着我需要标记所有这些模型都是从EF Diagram重新生成的 - 这是我试图避免的 - 修改EF生成的类。

2 个答案:

答案 0 :(得分:0)

您可以修改T4模板(Create文件),将其标记为覆盖或新视图。基本类型的属性当然必须标记为虚拟。

我相信overriding会起作用,因为您观察到的行为似乎是由于您的self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 80, right: 0) 方法无法访问继承的属性(它只有基类的定义,而且它们不是虚拟的) 。也就是说,如果没有深入到您的设计中,我想这并不是您想要的。

您真正想要的是阻止代码生成器首先在派生类上发出属性,以便所有调用者使用基本定义。我建议您再次查看T4模板,看看是否无法添加与基本类型属性匹配的规则。或者,考虑自定义属性以匹配它们。

感觉有一种解决这个问题的一般方法,所以如果你能确认的话,考虑为EF团队制定一份报告(我没有多想过)。

但是,建议切换到Code-First方法。坦率地说,我很想自己推荐给你。

答案 1 :(得分:0)

我知道比赛已经晚了,但我偶然发现了一些相同的问题。任何人进入代码的第一点是遵循msdn。入门的主要内容是将 debug="true 添加到 .tt 文件的第一行,例如,<#@ template language="C#" debug="false" hostspecific="true"#> 变为 <#@ template language="C#" debug="true" hostspecific="true"#>。现在您可以通过右键单击 .tt 文件来调试代码。

我认为问卷所指的地方是 simpleProperties 文件中的 .tt。如果需要,您可以在此处添加 override 或其他关键字:)