EF 读/写无钥匙表

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

我有一个没有键的表,将 Id 作为唯一不可为空的列,我必须写入它,因此我必须在代码中定义键,选择可能用作键的列。

[Table("AvailableProducts")]
public class AvailableProducts
{
public int Id { get; set; }
public string? A { get; set; }
public string? B { get; set; }
public string? C { get; set; }
}

Id、A、B 列都可以是组合键。

根据我的背景设置:

modelBuilder.Entity<AvailableProducts>().HasKey(u => new
{
u.Id,
u.A,
u.B
});

调用 context.SaveChanges() 没有问题;数据被插入到我的表中。

问题出在尝试读取数据时。调用 context.ToListAsyc();

我收到错误: 数据为空。无法对 Null 值调用此方法或属性。

如果我设置 modelBuilder.Entity().HasNoKey(); 我没有收到错误并获取我需要的数据,但我无法不再保存数据,因为 EF 确实需要密钥来写入。

我尝试将属性更改为 [Key][Required] 并从 string? 更改为 string 但似乎不起作用,我可以保存或读取,但不能同时保存和读取。

c# entity-framework asp.net-web-api
1个回答
0
投票

您的情况是实体框架 (EF) 中的一个不寻常的场景,因为 EF 是围绕拥有键的实体的想法而设计的。由于各种原因,包括潜在的数据不一致,通常不建议使用没有唯一键的表。

但是,针对你现在的情况:

1.单独的实体模型

您可以将模型分开进行读取和写入。

阅读模型

[Table("AvailableProducts")]
public class AvailableProductsRead
{
    public int Id { get; set; }
    public string? A { get; set; }
    public string? B { get; set; }
    public string? C { get; set; }
}

写作模型

public class AvailableProductsWrite
{
    public int Id { get; set; }
    public string A { get; set; }
    public string B { get; set; }
    public string? C { get; set; }
}

2.在 DbContext 中配置模型

您需要调整 DbContext 中的模型配置。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // For writing
    modelBuilder.Entity<AvailableProductsWrite>()
        .ToTable("AvailableProducts")
        .HasKey(u => new
        {
            u.Id,
            u.A,
            u.B
        });

    // For reading
    modelBuilder.Entity<AvailableProductsRead>()
        .HasNoKey()
        .ToView("AvailableProducts");
}

3.使用方法

以下是使用这两种模型的方法:

写入(插入新记录)

var newProduct = new AvailableProductsWrite { Id = 1, A = "valueA", B = "valueB", C = "valueC" };
context.Add(newProduct);
await context.SaveChangesAsync();

阅读

var products = await context.Set<AvailableProductsRead>().ToListAsync();

注:

此解决方案旨在解决您遇到的限制。如果可以的话,请考虑重构您的数据库架构,以在将来包含正确的主键和唯一键。

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