【问题标题】:EF Core : define 1 to 1 AND 1 to many between the same tablesEF Core:在同一张表之间定义 1 对 1 和 1 对多
【发布时间】:2019-01-11 05:53:23
【问题描述】:

我有两张表,为了争论,我们称它们为ProfileSessionProfile 有一个当前活动的会话(可选),并且所有会话都必须链接到配置文件(即使是那些不活动的)。

所以我们在CurrentSessionId 上拥有SessionProfile 之间的一对一关系,以及ProfileSession 之间的一对多关系。

问题是如何在实体框架代码优先构建它?

我有我的两个实体

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'

我正在尝试做的事情可能吗?是否应该以其他方式定义?

  • EF Core 版本:2.2.1
  • 数据库提供者:Microsoft.EntityFrameworkCore.SqlServer
  • 操作系统:Windows 10

【问题讨论】:

    标签: c# entity-framework-core ef-core-2.1 ef-core-2.2


    【解决方案1】:

    我能够通过明确定义键,然后在设置当前会话之前分别创建配置文件和会话来使其工作。

    实体

    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();
    

    如果您尝试将会话直接应用于配置文件,则会创建循环依赖项,因此您必须先创建它们并保存。然后,设置当前并再次保存。

    【讨论】:

    • 感谢您的回答,看来我必须弄脏我的类定义+调用代码才能实现这一点,并且还要保存到数据库两次:-(
    • 这可能被认为是一个错误,因为它不是一个实际的循环依赖。您可以在 EF Core 的 Github 页面上发布此问题。 github.com/aspnet/EntityFrameworkCore/issues
    猜你喜欢
    • 1970-01-01
    • 2015-11-08
    • 2021-11-25
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-01
    相关资源
    最近更新 更多