gpt4 book ai didi

c# - 如何使用延迟加载和单表继承从数据库中获取数据

转载 作者:搜寻专家 更新时间:2023-10-30 21:59:19 25 4
gpt4 key购买 nike

我有一个设置了延迟加载的数据库(这是必需的)。我还有一个 ASP.NET MVC 应用程序连接到数据库和“做事”。该数据库是根据我在一个单独项目中的类建模的。

我目前有 3 个使用继承的类:

public class DeliveryNotification
{
[Key]
public int Id { get; set; }

public Status Status { get; set; }
}

.

    public class TrackedDelivery : DeliveryNotification
{
[Required]
public DateTime Date { get; set; }

[Required]
public DateTime Time { get; set; }
}

.

public class SignedForDelivery : TrackedDelivery
{
[Required]
public string Image { get; set; }

}

这些都使用名为“DeliveryNotification”的单个表存储在数据库中

我已获得一个 DeliveryNotification Id,并希望获取所有信息。

在我的一个 Controller 中是这个方法:

var query = (from s in context.SignedForDeliverys
where s.Id == id
select s
).SingleOrDefault();

^ 尽管有带有 ID 的 DeliveryNotification,这将返回 null

var deliveryNotifications = context.DeliveryNotifications.SingleOrDefault(o => o.Id == id);

^ 这将只返回 ID 和状态。

假设我已经获得了一个 ID,我该如何返回(最好是 SignedForDeliverys)所有数据?

编辑:试图添加一个包含:

var signedForDeliverys = (from s in context.SignedForDeliverys.Include("TrackedDelivery ").Include("DeliveryNotification")
select s).ToList();

然后我得到这个错误:

An exception of type 'System.InvalidOperationException' occurred in EntityFramework.SqlServer.dll but was not handled in user code

Additional information: A specified Include path is not valid. The EntityType 'ClassLibrary.SignedForDelivery' does not declare a navigation property with the name 'TrackedDelivery'.

最佳答案

如果您想要一个SignedForDelivery,您可以...

context.DeliveryNotifications.OfType<SignedForDelivery>().Single(n => n.Id == id)
// or .Find(id)

或者如果每个子类型都有 DbSet 属性...

context.SignedForDeliveries.Single(n => n.Id == id) // or .Find(id)

...您已获得所有数据。

但是关于这个还有很多话要说。

从您的描述来看,在事先不知道类型的情况下通过 Id 获取对象似乎是一个业务案例(或用例)。如果是这样,我认为您不应该使用继承。您唯一可以做的就是检索 DeliveryNotification,然后尝试将其转换为所有继承的类型以查看它是什么(因为鉴别器字段不是类模型的一部分)。这很笨拙。

我不会通过继承来解决这个问题。我会使用一种类型,获取记录,然后决定哪些数据是相关的,例如通过根据现在可见的 Type 属性将其映射到特定的 View 模型或域类。这可以通过策略 模式来完成,这是组合模式之一。 (指的是“组合优于继承”的争论)。

此外,对于 TPH 继承(一个表),您不能强制要求特定属性(如 Image)是必需的,因为它们在数据库表中应该可以为空。这是一个“软”要求,因为它的实现取决于软件。其他继承方案,TPT、TPC,确实允许强有力的执行,但它们也有其他缺点。

简而言之,继承本身并不总是最好的模式,结合 ORM 通常最好避免继承。

关于c# - 如何使用延迟加载和单表继承从数据库中获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23414875/

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