我有两个表,为了便于讨论,我们将它们称为Profile
和Session
。 Profile
具有当前活动的会话(可选),并且所有会话都必须链接到配置文件(即使是未活动的会话)。
因此,我们在Session
上的Profile
和CurrentSessionId
之间是一对一的关系,在Profile
和Session
之间是一对多的关系
问题是如何先在Entity Framework代码中构建它?
我有两个实体
public class Profile
{
public Guid Id { get; set; }
public Session CurrentSession { get; set; }
}
public class Session
{
public Guid Id { get; set; }
}
和两种类型的配置
public class ProfileTypeConfiguration : IEntityTypeConfiguration<Profile>
{
public void Configure(EntityTypeBuilder<Profile> builder)
{
builder.ToTable("Profile");
builder.HasKey(x => x.Id);
builder.HasOne(x => x.CurrentSession)
.WithOne()
.HasForeignKey<Profile>("CurrentSessionId")
.HasConstraintName("FK_CurrentSession_Profile")
.IsRequired(false);
}
}
public class SessionTypeConfiguration : IEntityTypeConfiguration<Session>
{
public void Configure(EntityTypeBuilder<Session> builder)
{
builder.ToTable("Session");
builder.HasKey(x => x.Id);
builder.HasOne<Profile>()
.WithMany()
.HasForeignKey("ProfileId")
.HasConstraintName("FK_Profile_CurrentSession")
.IsRequired();
}
}
所有这些操作均使用正确的列和外键按预期生成数据库模式。当我尝试将配置文件插入数据库时出现问题
var profile = new Profile
{
Id = Guid.NewGuid(),
CurrentSession = new Session
{
Id = Guid.NewGuid()
}
};
ctx.Profiles.Add(profile);
ctx.SaveChanges();
这时我得到SqlException
的话
INSERT语句与FOREIGN KEY约束“ FK_Profile_CurrentSession”冲突
在探查器中查找,插入不包括Profile
记录,它只是试图插入Session
exec sp_executesql N'SET NOCOUNT ON;
INSERT INTO [Session] ([Id], [ProfileId])
VALUES (@p0, @p1);
',N'@p0 uniqueidentifier,@p1 uniqueidentifier',@p0='AE96BD5F-FB0D-4E02-8E97-FBEFE4EF1382',@p1='00000000-0000-0000-0000-000000000000'
我想做的是可能的吗?应该用其他方式定义它吗?
答案 0 :(得分:0)
我能够通过明确定义键,然后在设置当前会话之前分别创建配置文件和会话来使其工作。
实体
public class Profile
{
public Guid Id { get; set; }
public Guid? CurrentSessionId { get; set; }
public Session CurrentSession { get; set; }
}
public class Session
{
public Guid Id { get; set; }
public Guid ProfileId { get; set; }
}
类型配置
public class ProfileTypeConfiguration : IEntityTypeConfiguration<Profile>
{
public void Configure(EntityTypeBuilder<Profile> builder)
{
builder.ToTable("Profile");
builder.HasKey(x => x.Id);
builder.HasMany<Session>()
.WithOne()
.HasForeignKey(e => e.ProfileId)
.HasConstraintName("FK_Profile_CurrentSession")
.IsRequired();
builder.HasOne(x => x.CurrentSession)
.WithOne()
.HasForeignKey<Profile>("CurrentSessionId")
.HasConstraintName("FK_CurrentSession_Profile")
.IsRequired(false);
}
}
public class SessionTypeConfiguration : IEntityTypeConfiguration<Session>
{
public void Configure(EntityTypeBuilder<Session> builder)
{
builder.ToTable("Session");
builder.HasKey(x => x.Id);
}
}
程序。
var profileId = Guid.NewGuid();
var sessionId = Guid.NewGuid();
var profile = new Profile
{
Id = profileId,
};
var session = new Session
{
Id = sessionId,
ProfileId = profileId
};
ctx.Profiles.Add(profile);
ctx.Sessions.Add(session);
ctx.SaveChanges();
profile.CurrentSession = session;
ctx.SaveChanges();
如果您尝试将会话直接应用于配置文件,它将创建循环依赖项,因此您必须先创建它们并保存。然后,设置电流并再次保存。