实体框架CTP5代码优先:使用非基本类型作为密钥

时间:2011-01-26 08:06:15

标签: c# ef-code-first entity-framework-ctp5

我有一个项目有很多数据结构,我想在其中引入一个数据库。我正在研究实体框架CTP5的代码优先功能。

现在,我为每种类型使用不同的标识符类型(例如TypeAIdentifier,TypeBIdentifier等)。这很好,因为它在使用这些标识符时允许类型安全。问题是我似乎无法让EF使用非基本类型作为标识符。 http://blogs.msdn.com/b/efdesign/archive/2010/03/30/data-annotations-in-the-entity-framework-and-code-first.aspx中有一个提示:

KeyAttribute 

KeyAttribute is used to specify that a property/column is part of the primary 
key of the entity and applies to scalar properties only. 

确实,以下程序会引发异常:

class Program
{
    static void Main(string[] args)
    {
        MyDb db = new MyDb();
        db.SaveChanges();
    }
}

class MyDb : DbContext
{
    public DbSet<MyObject> MyObjects { get; set; }
}

class MyObject
{
    [Key] public MyIdentifierType MyId { get; set; }
    public int IntValue { get; set; }
}

class MyIdentifierType
{
    public int UniqueId { get; set; }
}

奇怪的是,这个程序抛出了一个MissingMethodException(“没有为此对象定义的无参数构造函数”),但我确信这与KeyAttribute有关,因为以下任何一个都会使程序运行:

  1. 删除[Key];或
  2. 将[Key]移动到IntValue。
  3. 如何让EF将我的标识符类映射为PK?想到两个选项:

    1. 找出一种让EF使用非基本类型作为PK的方法。
    2. 将'int'作为PK并获取EF以将此'int'转换为MyIdentifier(这样做的缺点是,如果我决定使用除'int'以外的其他内容,我将不得不同时更新MyIdentifier和映射,但它至少会让我保留标识符类型的安全性)。我认为Function Imports会让我这样做,但它似乎是建立在存储过程之上的。
    3. 有没有办法实现这个目标?

1 个答案:

答案 0 :(得分:0)

我将带有属性的密钥转换为自定义类型。

public class MyObject
{
    public int Id { get; set; }

    public int IntValue { get; set; }

    public MyIdentifierType MyId
    {
        get { return new MyIdentifierType {UniqueId = Id}; } 
        set { Id = value.UniqueId; }
    }
}