gpt4 book ai didi

entity-framework-core - EF Core 2.0 多重一对一关系

转载 作者:行者123 更新时间:2023-12-04 02:58:53 24 4
gpt4 key购买 nike

我正在尝试创建一个具有 Customer 的模型两个引用 Address 的实体实体:BillingAddressShippingAddress .

客户

public class Customer
{
public Guid CustomerId { get;set;}

public Guid? BillingAddressId { get; set; }
public Address BillingAddress { get; set; }

public Guid? ShippingAddressId { get; set; }
public Address ShippingAddress { get; set; }
}

地址
public class Address
{
public Guid AddressId { get; set; }

public Customer Customer { get; set; }
public Guid CustomerId { get; set; }
}

OnModelCreating
modelBuilder.Entity<Address>(eb =>
{
eb.HasOne(e => e.Customer).WithOne(o => o.BillingAddress).OnDelete(DeleteBehavior.Cascade);
});

modelBuilder.Entity<Address>(eb =>
{
eb.HasOne(e => e.Customer).WithOne(o => o.ShippingAddress).OnDelete(DeleteBehavior.Cascade);
});

尝试创建迁移时出现以下错误:
Cannot create a relationship between 'Customer.ShippingAddress' and 'Address.Customer', because there already is a relationship between 'Customer.BillingAddress' and 'Address.Customer'. Navigation properties can only participate in a single relationship.
我正在尝试配置模型,以便在删除客户时也删除引用的地址。我希望能够在不将地址加载到上下文中并依赖数据库进行级联的情况下执行此操作。

最佳答案

地址和客户之间的关系是多对一的(由地址上的外键 CustomerId 确定)。这意味着您需要在客户实体上指定地址集合。

public class Customer
{
public Guid CustomerId { get; set; }
public string Name { get; set; }

public virtual ICollection<Address> Addresses { get; set; }
}

所以我们需要一些其他的方法来确定哪个地址用于计费,哪个地址用于运输:
public class Address
{
public Guid AddressId { get; set; }
public bool IsBillingAddress { get; set; }
public bool IsShippingAddress { get; set; }
public Guid CustomerId { get; set; }
public virtual Customer Customer { get; set; }
}

然后, OnModelCreating您可以这样做以从客户那里引用您的地址并添加级联删除行为:
modelBuilder.Entity<Customer>()
.HasMany(c => c.Addresses)
.WithOne(a => a.Customer)
.OnDelete(DeleteBehavior.Cascade);

这给我们留下了一个额外的小问题——客户当前可以有多个账单地址或多个送货地址,因此我们需要添加某种形式的约束:
modelBuilder.Entity<Address>()
.HasIndex(a => new { a.CustomerId, a.IsBillingAddress })
.HasName("UQ_CustomerBillingAddress")
.IsUnique(true)
.HasFilter("IsBillingAddress = 1");

modelBuilder
.Entity<Address>()
.HasIndex(a => new { a.CustomerId, a.IsShippingAddress })
.HasName("UQ_CustomerShippingAddress")
.IsUnique(true)
.HasFilter("IsShippingAddress = 1");

这将允许客户拥有任意数量的地址,但最多只有一个帐单地址和一个送货地址。

关于entity-framework-core - EF Core 2.0 多重一对一关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49440598/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com