[实体框架核心无键导航问题

问题描述 投票:0回答:1

我正在为我的公司构建概念证明。我们有一个现有的平台,将用现代技术逐步替代。目前,我只能使用现有的数据库,该数据库具有多个无密钥表。我正在构建一个Blazor WebAssembly应用程序,该应用程序使用gRPC调用.net核心Web应用程序。我的问题是我正在使用EF Core与现有数据库通信,但是在调用DbContext.Attach(shipment)

时出现异常
"The navigation '' cannot be added because it targets the keyless entity type 'Document'. Navigations can only target entity types with keys."

[DocumentAttachDbContext的实体的导航属性。

Shipment是一个非常大且复杂的数据结构,深入了很多层。有没有一种方法可以避免必须在模型的结构内为每个实体DbContext.Entry(entity).State = EntityState.Added设置实体状态?

或者可能将DbSet的CRUD操作映射到存储过程?

编辑

这里是该模式的大大缩短的版本,但这仅是与问题有关的一切。

public class Shipment
{
    public int Id { get; set; }
    // 60 other properties

    public virtual ICollection<Document> Documents { get; set; }
}

public class Document
{
    public int ShippingId { get; set; }
    public string DocumentType { get; set; }
    public byte[] Content { get; set; }

    public virtual Shipment Shipment { get; set; }
}

[当我尝试将Shipment实体附加到DbContext或手动设置其状态时,出现上述异常。

同样,我目前无法更改数据库架构,并且有许多类似于Document的其他模型都没有密钥或添加密钥的方法。

编辑2

我意识到这需要进一步说明。显然,DbContext将无法插入/更新/删除,因为如果没有密钥,它将不知道如何操作。我只需要能够在获取Shipping实体并设置导航属性Documents时阅读。但是保存Shipping时,只需完全忽略导航属性即可。

c# entity-framework .net-core entity-framework-core asp.net-core-2.1
1个回答
0
投票

如果该Document类反映了文档表的完整架构,那么您将不能,并且可能不应尝试通过EF导航属性关联文档。虽然模式可以通过没有PK的表中的1向关系来正常运行,但是EF无法以这种方式管理关系。您如何期望将一个文档与另一个文档区分开?该系统可能永远不需要,但作为一个ORM,它被设计为可靠地加载和管理数据,这是必需的。

通常在没有PK的表中,只要有足够的字段来唯一区分记录,就可以通过定义键来满足EF。例如,ShippingId + CreatedAt,必要时还可以创建CreatedBy。但是,对于概述的架构,只有二进制内容不能用作键的一部分。

如果无法调整架构以引入无意义的键(所有表都应具有PK),那么我想说,您唯一的选择是就EF而言删除关联,并完全由Shipment分别加载文档。对于可能很少使用的潜在大型二进制数据,具有导航属性可能会带来潜在危险,因为尝试将其Include或通过诸如序列化程序之类的异常加载代理意外触发可能会使系统瘫痪。

© www.soinside.com 2019 - 2024. All rights reserved.