访问生成EF模型中的公共代码值表

本文关键字:代码 EF 模型 访问 | 更新日期: 2023-09-27 18:01:48

我有一个数据库,它使用一个自定义模型来记录查找值(即状态、类型等)。所以在所有的数据库表中,有各种列,比如state_cdv_id,它会存储一个整数,并引用code_value表来获取状态的值(即。"CA","AK"等)。

我想映射我的EF模型,这样我就可以访问所有这些字段的代码值,我不想在每个实体的部分类中手动完成它…这是大量的重复。我希望能够访问我的代码值,比如:MyPerson。声明并获取字符串"CA",例如。

如果我要手动操作,那么我将不得不多次重复单个getter的内容:

    public string State
    {
        get
        {
            MyEntityContext c = new MyEntityContext();
            return c.CodeValues.Single(cv => cv.Id == RecordStatusCdvId).Value;
        }
    }

我不知道最好的方法是什么:改变T4模板,添加属性属性到某些字段,然后以编程方式添加一个get到那些,或其他东西。

帮忙吗?

访问生成EF模型中的公共代码值表

如果实体和code_value表之间存在1:1的关系,则实体应该已经具有State属性,默认情况下该属性默认为null,然后您可以通过在DB查询中使用Include来填充它:

var foo = context.MyEntities.Include( x => x.State);

您的示例代码是非常错误的,因为它使您的实体依赖于上下文(而且您没有处理它)。整个POCO方法只是为了避免这种情况(POCO T4生成器和DbContext T4生成器)。

如果你与数据库中的查找表有关系,EF将为你创建导航属性。如果你在数据库中没有这样的关系,你使用的是EDMX文件,你仍然可以在你的模型中创建这样的关系,你将再次获得查找表的导航属性。一旦你有了导航属性,你可以简单地输入:

string code = myEntity.State.Code;

但是导航属性必须通过即时加载(如@BrokenGlass所述)或延迟加载来加载。

如果你不喜欢导航属性的想法,你仍然希望State属性只显示状态的代码,你必须理解它的意思:如果你映射实体的方式,它将是只读的,因为EF将无法转换复合实体回真实的表,必须更新。可以以您想要的方式映射实体,但它被认为是高级(并且大多数情况下不需要)的场景,只有当您有EDMX文件(不使用代码优先方法)时才能工作。选项是:

  • 创建数据库视图并将视图映射到新实体
  • 在EDMX(以XML形式打开)文件中手动创建DefiningQuery并将其映射到一个新的实体(一旦你这样做,你就不能从数据库更新你的模型或从模型生成数据库)
  • 在EDMX(以XML形式打开)文件中手动创建QueryView并将其映射到新实体(这需要原始实体已经映射)

对于每个想要这样映射的表都必须这样做。无论如何,手动更改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  
               };