gpt4 book ai didi

c# - 将一对多公开为一对零/一

转载 作者:太空宇宙 更新时间:2023-11-03 12:56:01 25 4
gpt4 key购买 nike

我正在现有数据库上尝试模型优先的方法。我无法以任何方式更改数据库方案。

这个数据库有一组有趣的关系:User 与 Address 有一对多的关系。但是,地址有一个“IsActive”字段,对于任何给定用户,只有一个地址处于事件状态。

我正在寻找一种方法让 Entity Framework 理解这一点,以便开发人员在他们的模型中拥有这种关系,就好像它是一对零/一对一的关系:user.Address.Line1 .

我需要一个真正的导航属性。我不只是试图避免每次都必须重复 user.Addresses.SingleOrDefault(c => c.IsActive).Line1。真正的导航属性允许更复杂的场景,例如从数据库延迟加载或预先加载,或过滤:usaCust = customers.Where(c => c.Address.Country == "USA"); .

最佳答案

您可以简单地向您的实体添加一个 ActiveAddress 属性,并使用它来获取/设置适当的地址为事件地址。

这将有效地为每个用户提供零个或一个 ActiveAddresses,可以将其设置为 Addresses 集合的成员,或设置为 null。一次只有一个地址处于事件状态。

public class User
{
[Key]
public int ID { get; set; }

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

[NotMapped]
public Address ActiveAddress
{
get { return Addresses == null ? null : Addresses.Where(t => t.IsActive).FirstOrDefault(); }
set
{
if (Addresses != null)
{
//set all addresses inactive
Addresses.ForEach(t => t.IsActive = false);
//set specified address as active if not null
if(value != null)
value.IsActive = true;
}
}
}
}

public class Address
{
[Key]
public int ID { get; set; }

public string FullAddress { get; set; }

public bool IsActive { get; set; }

public int UserID { get; set; }

[ForeignKey("UserID")]
public virtual User User { get; set; }
}

要查询此内容,您需要在引用您的 ActiveAddress 字段之前枚举并使用 Linq to Objects,因为它不存在于数据库中。如果您的客户和/或地址表中有大量记录,这可能不可行。

var usaCustomer = c.Customers.ToList().Where(t => t.ActiveAddress.Country == "USA").FirstOrDefault();

要使用 Linq to Entities,我目前能想到的唯一方法是通过地址 dbset 查询您的集合,这与您想做的相反,但仍会在数据库端执行。

var usaCustomer = c.Customers.Where(t => t.Addresses.Any(a => a.IsActive && a.Country == "USA")).FirstOrDefault();

关于c# - 将一对多公开为一对零/一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33827347/

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