微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 实体框架5.0b2代码优先:同一个表的一对多和一对一,WITH Cascade Delete

经过几个小时的反复试验,我达到了这个 thread,解释了如何建立一对多关系和一对一的关系,使用相同的两种类型.

但是,我无法使用Cascade Delete:

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关系时才会发生这种情况(参见下面的代码),我认为这会产生无效的引用.我只是想知道是否有更好的方式来表示这一点.

示例代码

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

解决方法

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

一个.

如何使用这样的3个表:

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作为最佳选择.

我确信从同一个源表到同一个目标表有两个关系并不是一个好主意……它可能会打破关于数据库最佳实践的一些规则或模式.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐