微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Entity Framework Core - 批量加载具有导航属性的表我们是否必须手动管理 EntityState.Unchanged?

如何解决Entity Framework Core - 批量加载具有导航属性的表我们是否必须手动管理 EntityState.Unchanged?

使用 EF Core 5,想象一个带有 Car 表的简单数据模型,该表的导航属性Manufacturer

public class Car
{
    public int CarId { get; set; }
    public string ModelName { get; set; }
    public Manufacturer Manufacturer { get; set; }
}

public class Manufacturer
{
    public int ManufacturerId { get; set; }
    public string Name { get; set; }
    public string Country { get; set; }
}

假设我们要装载 2 辆汽车,它们都由同一制造商制造,ID 为 1。所以我们的目标是将表格填满:

enter image description here

现在假设我们必须批量加载这些数据。 1 号车有一个批次,2 号车有一个批次。在下面的示例代码中,每个批次后都会保存数据,并重新创建数据库上下文。

以下是运行良好的示例代码

//-----------------------------------------------------------
// LOAD BATCH 01
//-----------------------------------------------------------
// Create entry for Mini car,manufactured by Leyland
using (var db = new EfdbContext(CONNECTION_STRING))
{
    var manuf = new Manufacturer() { ManufacturerId = 1,Name = "Leyland",Country = "UK" };
    db.Cars.Add(
        new Car()
        {
            CarId = 1,ModelName = "Mini",Manufacturer = manuf,});
    db.SaveChanges();
}

//-----------------------------------------------------------
// LOAD BATCH 02
//-----------------------------------------------------------
// Create entry for Daimler car,also manufactured by Leyland
using (var db = new EfdbContext(CONNECTION_STRING))
{
    // Retrieve the existing Leyland manufacturer record
    var manuf = db.Manufacturers
        .AsNoTracking()
        .Where(t => t.ManufacturerId == 1)
        .FirstOrDefault();
    if (manuf == null) throw new Exception("Should never happen,test is messed up");

    var car = new Car()
    {
        CarId = 2,ModelName = "Daimler",};
    // Tell EF not to try to update Manufacturer table
    db.Entry(car.Manufacturer).State = EntityState.Unchanged; // [1] commenting out this line causes error
    db.Cars.Add(car);
    db.SaveChanges();
}

请参阅上面带有注释 [1] 的行。如果该行被注释掉,则加载过程会错误提示 'UNIQUE constraint Failed: Manufacturers.ManufacturerId,因为 EF 正在尝试插入到 Manufacturer 表中。

以上都有效,但它是丑陋的。想象一个有数百个导航属性的表格。必须管理所有这些,确定我们是否需要为每个字段和每个记录设置 EntityStage.Unchanged 感觉很笨拙。

有没有更好的办法?这是我们说这个过程不太适合 ORM 而我们恢复到纯 sqlthe bulk loading tools that there are 之一的地方吗?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。