我有一个数据库,它使用自定义模型来记录查找值(即状态,类型等)。因此,在所有数据库表中,有各种名为state_cdv_id的列,它们将存储一个整数并引用code_value表来获取该状态的值(即“CA”,“AK”等)。
我想映射我的EF模型,以便我可以访问所有这些字段的代码值,我不想在每个实体的部分类中手动执行...这是很多重复。所以我希望能够访问我的代码值,例如:MyPerson.State,然后返回字符串“CA”。
如果我要手动完成,那么我将不得不多次重复使用单个getter:
public string State
{
get
{
MyEntityContext c = new MyEntityContext();
return c.CodeValues.Single(cv => cv.Id == RecordStatusCdvId).Value;
}
}
我不知道最好的方法是什么:更改T4模板,将属性属性添加到某些字段,然后以编程方式添加获取或其他内容。
任何帮助?
答案 0 :(得分:1)
如果实体和code_value
表之间存在1:1关系,则实体应该已经具有State
属性,默认情况下默认为null,然后您可以填充它在数据库查询中使用Include
:
var foo = context.MyEntities.Include( x => x.State);
答案 1 :(得分:1)
您的示例代码非常错误,因为它会使您的实体依赖于上下文(而且您不会丢弃它)。整个POCO方法只是为了避免这种情况(POCO T4发生器和DbContext T4发生器)。
如果您与数据库中的查找表有关系,EF将为您创建导航属性。如果您在数据库中没有这样的关系并且您正在使用EDMX文件,您仍然可以在模型中创建这样的关系,并且您将再次获得导航属性到查找表。拥有导航属性后,您可以执行以下操作:
string code = myEntity.State.Code;
但导航属性必须通过急切加载(如描述的@BrokenGlass)或延迟加载来加载。
如果你不喜欢导航属性的想法,并且你仍然希望State
属性只显示状态代码,你必须理解它的含义:如果你以这种方式映射实体它将被读取 - 因为EF无法将复合实体转换回必须更新的实际表。可以按照您想要的方式映射实体,但它被视为高级(并且通常不需要)场景,仅当您具有EDMX文件(不使用代码优先方法)时才有效。选择是:
您必须为每个需要此类映射的表执行此操作。无论如何,不需要手动更改EDMX的复杂性,因为您可以简单地创建自定义类,如:
public class SomeViewModel // I suppose your main target is to have codes in presentation layer
{
public string SomeData { get; set; }
public string State { get; set; }
}
并使用投影查询
如果您有导航属性:
var data = from x in context.SomeEntities
select new SomeViewModel
{
SomeData = x.SomeData,
State = x.State.Code
};
如果您没有导航属性
var data = from x in context.SomeEntities
join y in context.LookupValues on x.LookupId equals y.Id
select new SomeViewModel
{
SomeData = x.SomeData,
State = y.Code
};