C# 填充基类而不是子类
我为自己编写了一个库来帮助查找通用数据库。当我使用它时,我得到一个所有属性都为空的类。但是,基类已正确填充。C# 填充基类而不是子类,c#,asp.net-mvc,entity-framework,generics,C#,Asp.net Mvc,Entity Framework,Generics,我为自己编写了一个库来帮助查找通用数据库。当我使用它时,我得到一个所有属性都为空的类。但是,基类已正确填充。产品变量已正确填充。如何使代码填充派生类(TModel entity)?当我在dataserviceCreate方法(代码内注释)中设置断点时,以下是Locals/Autos窗口中的结果: 基于GenericLookupModel类的TModel: public abstract class GenericLookupViewModel { [Key] public in
产品
变量已正确填充。如何使代码填充派生类(TModel entity
)?当我在dataserviceCreate
方法(代码内注释)中设置断点时,以下是Locals/Autos窗口中的结果:
基于GenericLookupModel类的TModel:
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; }
}
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);
}
}
公共类PrimaryFocusController:GenericLookupViewModelController
{
公共覆盖操作结果创建(PrimaryFocusViewModel查找)
{
SetBrowsingUser(AppUser.Login);
返回base.Create(查找);
}
}
当我编译库时,我会收到警告消息,这些消息可能需要执行以下操作:
警告CS0108:'DataLayer.tblkp_PrimaryFocus.id'隐藏继承的成员'MyLib.Model.GenericLookupModel.id'。如果要隐藏,请使用新关键字。
警告CS0108:'DataLayer.tblkp_PrimaryFocus.value'隐藏继承的成员'MyLib.Model.GenericLookupModel.value'。如果要隐藏,请使用新关键字。
警告CS0108:'DataLayer.tblkp_PrimaryFocus.is_active'隐藏继承的成员'MyLib.Model.GenericLookupModel.is_active'。如果要隐藏,请使用新关键字。
警告CS0108:'DataLayer.tblkp_PrimaryFocus.created_on'隐藏继承的成员'MyLib.Model.GenericLookupModel.created_on'。如果要隐藏,请使用新关键字。
警告CS0108:'DataLayer.tblkp_PrimaryFocus.created_by'隐藏继承的成员'MyLib.Model.GenericLookupModel.created_by'。如果要隐藏,请使用新关键字。
警告CS0108:'DataLayer.tblkp_PrimaryFocus.modified_on'隐藏继承的成员'MyLib.Model.GenericLookupModel.modified_on'。如果要隐藏,请使用新关键字。
警告CS0108:'DataLayer.tblkp_PrimaryFocus.modified_by'隐藏继承的成员'MyLib.Model.GenericLookupModel.modified_by'。如果要隐藏,请使用新关键字。
DataLayer.tblkp_PrimaryFocus是使用DB First方法从EF生成的类
更新:User@code4life提出了一个很好的观点——将子类的所有属性标记为
virtual
(tblkp\u PrimaryFocus),但这意味着,每次从EF图重新生成模型时,我都需要标记所有这些模板——这正是我试图避免的——修改EF生成的类。您可以修改T4模板(.tt
文件),将其标记为覆盖或新的模板(视情况而定)。当然,基类型上的属性必须标记为虚拟
我相信重写会起作用,因为您观察到的行为似乎是由于您的Create
方法无法访问继承的属性(它只有基的定义,并且它们不是虚拟的)。也就是说,在没有深入了解您的设计的情况下,我想这并不是您想要的
您真正想要的是防止代码生成器首先在派生类上发出属性,以便所有调用方都使用基定义。我建议您首先再次查看T4模板,看看是否可以添加与基本类型的属性匹配的规则。或者,考虑自定义属性来匹配它们。
感觉有一个通用的方法来解决这个问题,所以如果你能确认的话,考虑为EF团队制定一份报告(我还没想好)。
不过,我们希望建议转向代码优先的方法。坦白地说,我很想亲自向您推荐。我知道比赛已经晚了,但我在这里遇到了一些同样的问题。任何人进入代码的第一点是遵循。开始的主要步骤是将
debug=“true
添加到.tt
文件的顶行,例如,
变成
。现在您可以通过右键单击.tt
文件来调试代码
我认为调查问卷所指的地方是
.tt
文件中的simpleProperties
。在这里,您可以添加override
或其他关键字,如果需要:)您需要将您希望在子类中重写的属性标记为virtual
。问题是子类是由数据库生成的Namaly by Entity Framework。如果我开始修改这些,我将不得不在每次从EF图生成模型时修改它们,我希望避免这种情况。我认为每次我将从.edmx文件中重新生成模型,.tt模板也将被删除overwritten@AdrianK.我鼓励你试试,我现在没有任何推荐信现在,但我记得情况并非如此。事实上,(C#)模型的重新生成“只是”模板的重新运行。只要您继续使用相同的EDMX,事情就应该按预期进行。
public class PrimaryFocusController : GenericLookupViewModelController<PrimaryFocusViewModel,tblkp_PrimaryFocus>
{
public override ActionResult Create(PrimaryFocusViewModel lookup)
{
SetBrowsingUser(AppUser.Login);
return base.Create(lookup);
}
}