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

时间:2011-07-08 23:43:03

标签: c# entity-framework-4.1

我有一个数据库,它使用自定义模型来记录查找值(即状态,类型等)。因此,在所有数据库表中,有各种名为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模板,将属性属性添加到某些字段,然后以编程方式添加获取或其他内容。

任何帮助?

2 个答案:

答案 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(打开为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  
               };