我的表格看起来像这样
Users
- UserID (PK)
- UserName
- ...
UserSettings
- UserID (PK)
- Settings
我的UserSetting实体看起来像这样
public class UserSetting
{
public UserSetting()
{
}
[Key]
[Column("UserID", TypeName ="nvarchar(128)")]
public string ID { get; set; }
[Required]
public string Settings { get; set; }
}
我希望UserSettings的PK将User中UserID的FK添加到UserSettings中的UserID,因为该关系应该是1:1(如果您想知道settings字段是前端刚刚转储的字符串)数据库作为json字符串,后端不关心里面的值)
如果我手动创建数据库并添加外键并且EF对此一无所知,这可以正常工作但我决定尝试让EF为这个项目创建数据库。有没有办法告诉EF创建该FK而不添加与任何一个实体的关系的实体属性?
答案 0 :(得分:5)
要在Code First 中创建关系,您需要在两端中至少有一个导航属性(这种关系称为单向关系)。典型的one to one relationship配置如下:
public class User
{
public User()
{
}
[Key]
[Column("ID", TypeName ="nvarchar(128)")]
public string ID { get; set; }
public string Name{ get; set; }
public virtual UserSetting UserSetting {get;set;}
}
public class UserSetting
{
public UserSetting()
{
}
[Key,ForeignKey("User"),Column("UserID")]
public string ID { get; set; }
//...
public virtual User User{get;set;}
}
现在,使用此模型,您不会向表中添加任何新列,它将是相同的,只是现在您将UserSettings
表的PK配置为关系的FK(您是什么正在努力实现)。
现在,正如我所说EF需要至少一个导航属性来创建关系。因此,如果需要,您可以删除UserSetting
导航。 User
上的属性,没关系,将数据注释保留在Id
的{{1}}上,UserSetting
导航属性足以使Code First创建关系。
答案 1 :(得分:0)
首先要为EF代码自动生成外键关系,您需要导航属性。
我发现解决此问题的最简单方法是手动更改迁移。
我的实体看起来像这样:
public class User
{
public User() { }
[Key]
public string ID { get; set; }
public string Name { get; set; }
}
public class UserSetting
{
public UserSetting() { }
[Key]
public string ID { get; set; }
public string Settings { get; set; }
}
执行迁移,生成以下迁移类:
...
CreateTable(
"dbo.Users",
c => new
{
ID = c.String(nullable: false, maxLength: 128),
Name = c.String(),
})
.PrimaryKey(t => t.ID);
CreateTable(
"dbo.UserSettings",
c => new
{
ID = c.String(nullable: false, maxLength: 128),
Settings = c.String(),
})
.PrimaryKey(t => t.ID);
...
现在更改与UserSetting表相关的CreateTable语句: 替换:
.PrimaryKey(t => t.ID);
与
.PrimaryKey(t => t.ID)
.ForeignKey("dbo.Users", t => t.ID);
不要忘记改变Down方法以包含DropForeignKey语句。