实体框架 5.0b2 代码优先:同一表的一对多和一对一,WITH 级联删除

本文关键字:一对多 一对一 删除 级联 WITH 0b2 框架 代码 实体 | 更新日期: 2023-09-27 18:34:09

经过几个小时的反复试验,我找到了这个线程,它解释了如何建立具有相同两种类型的一对多关系和一对一关系。

但是,我无法将其与级联删除一起使用:

抛出:"无法确定从属的有效排序 操作。由于外键约束,可能存在依赖关系, 模型要求,或存储生成的值。 (System.Data.UpdateException( 异常消息 ="无法确定 依赖操作的有效排序。依赖关系可能存在,原因 到外键约束、模型要求或存储生成 值.",异常类型 ="系统.数据.更新异常">

这只有在我不取消设置 1:1 关系(见下面的代码(时才会发生,我想这是有道理的,因为它会创建一个无效的引用。我只是想知道是否有更好的方法来表示这一点。

示例代码:

class Program
{
    static void Main(string[] args)
    {
        Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
        using (var ctx = new Context())
        {
            var user = new User();
            ctx.Users.Add(user);
            ctx.SaveChanges();
            var source = new PaymentSource();
            user.PaymentSources = new Collection<PaymentSource>();
            user.PaymentSources.Add(source);
            user.DefaultPaymentSource = source;
            ctx.SaveChanges();
            // if I don't do this, I get ordering exception
            user.DefaultPaymentSource = null;
            ctx.SaveChanges();
            ctx.Users.Remove(user);
            ctx.SaveChanges();
            Assert.Equal(0, ctx.Users.Count());
            Assert.Equal(0, ctx.PaymentSources.Count());
        }
    }
}
public class User
{
    public int Id { get; set; }
    public virtual ICollection<PaymentSource> PaymentSources { get; set; }
    public virtual PaymentSource DefaultPaymentSource { get; set; }
    public int? DefaultPaymentSourceId { get; set; }
}
public class PaymentSource
{
    public int Id { get; set; }
    public virtual User User { get; set; }
    public int UserId { get; set; }
}
public class Context : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<PaymentSource> PaymentSources { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<User>()
            .HasOptional(u => u.DefaultPaymentSource)
            .WithMany()
            .HasForeignKey(u => u.DefaultPaymentSourceId)
            .WillCascadeOnDelete(false);
        modelBuilder.Entity<PaymentSource>()
            .HasRequired(p => p.User)
            .WithMany(p => p.PaymentSources)
            .HasForeignKey(p => p.UserId)
            .WillCascadeOnDelete();
    }
}

实体框架 5.0b2 代码优先:同一表的一对多和一对一,WITH 级联删除

我列出了其他选项来描述您的抽象:

一个。

像这样使用 3 张表怎么样:

user 1-* paymentSource
user 1-0..1 DefaultPaymentSource
DefaultPaymentSource 0..1-1 PaymentSource

或者这个:

二.

user 1-* paymentSource
user 1-0..1 DefaultPaymentSource
DefaultPaymentSource --derive from--> PaymentSource

或者这个:

三.

user 1-* paymentSource
PaymentSource has addtional boolean field for "IsDefault"

我投票支持选项B作为最佳选项。

我确信将两个关系从同一源表发送到同一目标表将不是一个好主意......它可能违反了有关数据库最佳实践的一些规则或模式。