实体框架6外键使用字符串而不是源模型ID

时间:2016-02-01 15:26:43

标签: c# asp.net-mvc entity-framework entity-framework-6

我有以下(缩写)模型:

public class Item
{
public int id { get; set; }
public string itemId { get; set; }
... more properties ...
public virtual List<Detail> Details { get; set;}
}

public class Detail
{
[Key]
public int id { get; set; }

public string itemId { get; set; }
... more properties ...

// Navigation property
[ForeignKey("itemId")]
public virtual Item Item { get; set; }
}

如果我使用itemId作为int,它会创建FK,但它会将Item.ID链接到Detail.itemId - 我希望它链接{{1} } Item.itemId

我确信这是装饰品中缺少的东西,但似乎EF希望始终使用默认ID。

我希望这样做的原因是因为源数据是通过字符串ID链接的,我可以将其转换为Detail.itemId,但限制仍然存在,我希望每个表都是拥有它自己的int,直到我能确保源数据足够强大。

1 个答案:

答案 0 :(得分:2)

依赖项中的外键需要链接(编辑 - 通常是链接)到主体的主键。如果您希望这些是字符串,那么您需要做的就是遵循键和外键的命名约定::

public class Item
{
   //Code First infers that a property is a primary key if a property 
   //on a class is named “ID” (not case sensitive), 
   //or the class name followed by "ID"
   //so you could use "Id" for the name of the primary key
   public string ItemId { get; set; }

   //... more properties ...
   public virtual List<Detail> Details { get; set;}
}

public class Detail
{
   //Let's use DetailId as the key here because that is the convention 
   //we've used in the "Item" class
   public int DetailId { get; set; }


   /*Any property with the same data type as the principal primary key
   property and with a name that follows one of the following formats
   represents a foreign key for the relationship: 
   <navigation property name><principal primary key property name> (i.e.ItemItemId),
   <principal class name><primary key property name>(i.e. ItemItemId), 
   or <principal primary key property name>(i.e. ItemId). 
   If multiple matches are found then precedence is given in the order listed above.*/
   public string ItemId { get; set; }
   //... more properties ...

   public virtual Item Item { get; set; }
}

不需要属性,因为所有名称都遵循键和外键的命名约定。

现在,如果要向名为Item的{​​{1}}类添加一个不是主键(?!!)的字段,那么您需要告诉实体框架{{1} }是主键 - 您可以使用Id属性执行此操作:

ItemId

修改 在你的评论之后,它可能是非传统的,因为外键没有引用主键,但你没有与惯例联系在一起。您可以使用数据属性或流畅的api覆盖约定。

在这种情况下,您可以强制EF使用依赖项导航属性上的Key来执行此操作(我说&#34;可能&#34;因为我还没试过这个所以,实际上并不知道EF是否会抗议):

public class Item
{
   [Key]
   public string ItemId { get; set; }

   /*Because it is not the primary key, if you want it to be an Identity
   field, you may need to add the attribute*/
   [DatabaseGenerated(DatabaseGeneratedoption.Identity)]
   public int Id {get; set; }

}

参考:

Code first conventions

Relationships with Data Attributes

Relationships with the FluentAPI