我有以下(缩写)模型:
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
,直到我能确保源数据足够强大。
答案 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; }
}
参考: