Entity Framework 5.0b2代码优先:同一表的一对多和一对一,带有级联删除 [英] Entity Framework 5.0b2 Code First: One-To-Many and One-To-One for the same table, WITH Cascade Delete

查看:72
本文介绍了Entity Framework 5.0b2代码优先:同一表的一对多和一对一,带有级联删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

经过数小时的反复试验,我到达了线程,其中介绍了如何建立具有相同两种类型的一对多关系和一对一关系。

After several hours of trial and error, I reached to this thread which explains how to establish a One-To-Many relationship and a One-To-One relationship with the same two types.

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

However, I cannot get this to work with Cascade Delete:


抛出:无法确定相关
操作的有效顺序。由于外键约束,
模型要求或商店生成的值,因此可能存在依赖关系。
(System.Data.UpdateException)异常消息=无法确定
a依赖操作的有效顺序。由于
是由于外键约束,模型要求或存储生成的$ b,因此可能存在依赖关系$ b values。,异常类型= System.Data.UpdateException

Thrown: "Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values." (System.Data.UpdateException) Exception Message = "Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values.", Exception Type = "System.Data.UpdateException"

仅当我未取消设置1时才会发生:1关系(请参见下面的代码),考虑到它将创建无效的引用,我认为这是有意义的。我只是想知道是否有更好的方法来表示这一点。

This only happens if I don't unset the 1:1 relationship (see code below), which I guess makes sense given that it would create an invalid reference. I'm just wondering if there is a better way to represent this.

示例代码:

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


推荐答案

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

I listed other options to describe your abstraction:

A。

如何使用像这样的3个表:

How about using 3 tables like that:

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

或此:

B。

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

或以下方式:

C。

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

我对选项B投票是最好的。

I vote for choice B as best one.

我敢肯定,从同一个源表到同一个目标表有两个关系并不是一个好主意。它可能打破了有关数据库最佳实践的某些规则或模式。

I am certain that having two relations comming from the same source table to the same destination table is not going to be a good idea.. it is probably breaking some rule or pattern regarding databases best practice.

这篇关于Entity Framework 5.0b2代码优先:同一表的一对多和一对一,带有级联删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆