外键未更新(配置为依赖主体)
Foreign key not updated (configured with required principal-dependent)
流畅API 配置:
internal class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
Property(x => x.CSL).IsRequired();
//relational properties
HasRequired(x => x.UserType).WithMany(x => x.Users).HasForeignKey(x => x.UserType_ID).WillCascadeOnDelete(true);
HasRequired(x => x.TimelineVolumetry).WithRequiredPrincipal(x => x.User).WillCascadeOnDelete(true);
}
}
internal class TimelineVolumetryMap : EntityTypeConfiguration<TimelineVolumetry>
{
public TimelineVolumetryMap()
{
Property(x => x.AllowedWeeks).IsRequired();
//relational properties
HasRequired(x => x.User).WithRequiredDependent(x => x.TimelineVolumetry).WillCascadeOnDelete(true);
}
}
插入查询:
User u = new User();
u.CSL = csl;
u.UserType_ID = role;
u.TimelineVolumetry = new TimelineVolumetry();
u.TimelineVolumetry.User = u;
ctx.User.Add(u);
ctx.SaveChanges();
在数据库中插入一个用户后,我得到 User_ID = 0
TimelineVolumetry
。有没有办法在添加用户时自动设置 User_ID
或者我是否在设置外键后再次强制保存 TimelineVolumetry
?
public class TimelineVolumetry
{
public int ID { get; set; }
public int AllowedWeeks { get; set; }
//relational properties
public int User_ID { get; set; }
public User User { get; set; }
public TimelineVolumetry()
{
AllowedWeeks = 0;
}
}
我看到了一些可以在您的关系配置中改进的地方。首先,User
和TimelineVolumetry
之间的关系不需要配置两次,一次就够了。您也不需要配置与级联删除的关系。如果依赖实体上的外键不可为空(如您的情况),则 Code First 会在关系上设置级联删除,因此已经设置了它。
public class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
Property(x => x.CSL).IsRequired();
//relational properties
HasRequired(x => x.UserType).WithMany(x => x.Users).HasForeignKey(x => x.UserType_ID);
HasRequired(x => x.TimelineVolumetry).WithRequiredPrincipal(x => x.User);
}
}
public class TimelineVolumetryMap : EntityTypeConfiguration<TimelineVolumetry>
{
public TimelineVolumetryMap()
{
Property(x => x.AllowedWeeks).IsRequired();
}
}
关于插入,如果您同时创建两个实体,您应该这样做:
User u = new User();
//...
var tv= new TimelineVolumetry();
//set required properties of TimelineVolumetry entity
u.TimelineVolumetry =tv;
//u.TimelineVolumetry.User = u;// you don't need to do this
//...
ctx.User.Add(u);
ctx.SaveChanges();
这将在数据库中正确插入两个实体(包括外键列的值)。
更新
恐怕你想要的不是possible.You无法与未声明为PK的FK建立一对一关系,Entity Framework需要主键依赖也是外键,所以,要实现你想要的,你可以这样做:
public class TimelineVolumetry
{
public int AllowedWeeks { get; set; }
//relational properties
[Key, ForeignKey("User")]
public int User_ID { get; set; }
public User User { get; set; }
public TimelineVolumetry()
{
AllowedWeeks = 0;
}
}
那是使用Data Annotations,但是使用Fluent Api会这样:
// Configure User_Id as PK for TimelineVolumetry
modelBuilder.Entity<TimelineVolumetry>()
.HasKey(e => e.User_Id);
// Configure User_Id as FK for TimelineVolumetry
modelBuilder.Entity<User>()
.HasOptional(s => s.TimelineVolumetry) // Mark TimelineVolumetry is optional for User
.WithRequired(ad => ad.User); // Create inverse relationship
如果你想阅读更多关于这个主题的内容,我推荐你这个link。
流畅API 配置:
internal class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
Property(x => x.CSL).IsRequired();
//relational properties
HasRequired(x => x.UserType).WithMany(x => x.Users).HasForeignKey(x => x.UserType_ID).WillCascadeOnDelete(true);
HasRequired(x => x.TimelineVolumetry).WithRequiredPrincipal(x => x.User).WillCascadeOnDelete(true);
}
}
internal class TimelineVolumetryMap : EntityTypeConfiguration<TimelineVolumetry>
{
public TimelineVolumetryMap()
{
Property(x => x.AllowedWeeks).IsRequired();
//relational properties
HasRequired(x => x.User).WithRequiredDependent(x => x.TimelineVolumetry).WillCascadeOnDelete(true);
}
}
插入查询:
User u = new User();
u.CSL = csl;
u.UserType_ID = role;
u.TimelineVolumetry = new TimelineVolumetry();
u.TimelineVolumetry.User = u;
ctx.User.Add(u);
ctx.SaveChanges();
在数据库中插入一个用户后,我得到 User_ID = 0
TimelineVolumetry
。有没有办法在添加用户时自动设置 User_ID
或者我是否在设置外键后再次强制保存 TimelineVolumetry
?
public class TimelineVolumetry
{
public int ID { get; set; }
public int AllowedWeeks { get; set; }
//relational properties
public int User_ID { get; set; }
public User User { get; set; }
public TimelineVolumetry()
{
AllowedWeeks = 0;
}
}
我看到了一些可以在您的关系配置中改进的地方。首先,User
和TimelineVolumetry
之间的关系不需要配置两次,一次就够了。您也不需要配置与级联删除的关系。如果依赖实体上的外键不可为空(如您的情况),则 Code First 会在关系上设置级联删除,因此已经设置了它。
public class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
Property(x => x.CSL).IsRequired();
//relational properties
HasRequired(x => x.UserType).WithMany(x => x.Users).HasForeignKey(x => x.UserType_ID);
HasRequired(x => x.TimelineVolumetry).WithRequiredPrincipal(x => x.User);
}
}
public class TimelineVolumetryMap : EntityTypeConfiguration<TimelineVolumetry>
{
public TimelineVolumetryMap()
{
Property(x => x.AllowedWeeks).IsRequired();
}
}
关于插入,如果您同时创建两个实体,您应该这样做:
User u = new User();
//...
var tv= new TimelineVolumetry();
//set required properties of TimelineVolumetry entity
u.TimelineVolumetry =tv;
//u.TimelineVolumetry.User = u;// you don't need to do this
//...
ctx.User.Add(u);
ctx.SaveChanges();
这将在数据库中正确插入两个实体(包括外键列的值)。
更新
恐怕你想要的不是possible.You无法与未声明为PK的FK建立一对一关系,Entity Framework需要主键依赖也是外键,所以,要实现你想要的,你可以这样做:
public class TimelineVolumetry
{
public int AllowedWeeks { get; set; }
//relational properties
[Key, ForeignKey("User")]
public int User_ID { get; set; }
public User User { get; set; }
public TimelineVolumetry()
{
AllowedWeeks = 0;
}
}
那是使用Data Annotations,但是使用Fluent Api会这样:
// Configure User_Id as PK for TimelineVolumetry
modelBuilder.Entity<TimelineVolumetry>()
.HasKey(e => e.User_Id);
// Configure User_Id as FK for TimelineVolumetry
modelBuilder.Entity<User>()
.HasOptional(s => s.TimelineVolumetry) // Mark TimelineVolumetry is optional for User
.WithRequired(ad => ad.User); // Create inverse relationship
如果你想阅读更多关于这个主题的内容,我推荐你这个link。