使用ID属性以多对多插入未跟踪的实体

时间:2018-07-03 17:58:51

标签: c# entity-framework-core

我有一个同时具有参考数据和非参考数据的应用程序。

参考数据不会经常更改,因此我们决定将其缓存。

由于我们是从缓存中获取的,因此查询查询时不会跟踪参考数据。

我现在遇到一个问题,当我插入新的非参考数据实体时,它会尝试插入新的参考数据项。

一个例子:

public class Plant {
    public int Id { get; set; }
    public string Name { get; set; }
    public int FamilyId { get; set; }
    public Family Family { get; set; }
    public ICollection<PlantColour> PlantColours { get; set; }
}

public class Family {
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Plant> Plants { get; set; }
}

public class PlantColour {
    public int PlantId { get; set; }
    public int ColourId { get; set; }
    public Plant Plant { get; set; }
    public Colour Colour { get; set; }
}

public class Colour {
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<PlantColour> PlantColours { get; set; }
}

当尝试插入新的植物(家庭属性)集时,它将尝试插入新的家庭。我们只需设置外键字段Plant.FamilyId = myFamily.Id;

即可解决此问题

但是,对于像Plant.PlantColours这样的多对多关系,如果我想将“颜色”与植物相关联,则无法使用。

尤其是,上下文中的Colours被缓存,因此不会被跟踪。

如果我创建一个新的Plant,请从高速缓存的Colors中选择一种具有所需颜色名称的颜色,如果我还没有PlantId,该如何创建必要的plant.PlantColours填充?

我想避免再次为每个记录查询数据库,因为它将处理数千个记录。

1 个答案:

答案 0 :(得分:2)

您只需要避免引用未跟踪的对象,而使用其Id字段即可:

List<Colour> selectedColours = GetSelectedColours(); // colours from cache
Family selectedFamily = GetSelectedFamily(); // family from cache

var plant = new Plant
{
    Name = "Black alder",
    FamilyId = selectedFamily.Id // Family property is null
};

plant.PlantColours = selectedColours.Select(c => new PlantColour
{
    Plant = plant,
    ColourId = c.Id // Colour property is null
}).ToList();

myDbContext.Set<Plant>.Add(plant);
await myDbContext.SaveChangesAsync();