实体框架:抽象类的多对多关系,无需查询数据库即可修改

本文关键字:查询 数据库 修改 关系 框架 抽象类 实体 | 更新日期: 2023-09-27 18:16:32

使用实体框架,如果我有以下模型:

class Asset {
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<AssetGroup> Groups { get; set; }
}
class AssetGroup {
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Asset> Assets { get; set; }
}

将现有的资产添加到给定的组中,而不必查询数据库来加载相关的资产,这是相对简单的:

using(var context = new MyContext()) {
    AssetGroup assetGroup = context.AssetGroups.Find(groupId);
    // Create a fake Asset to avoid a db query
    Asset temp = context.Assets.Create();
    temp.Id = assetId;
    context.Assets.Attach(temp);
    assetGroup.Assets.Add(temp);
    context.SaveChanges();
}

然而,我现在有一个问题,我已经扩展了模型,以便有多个资产类型,作为继承层次结构实现。在这个过程中,Asset类被抽象了,因为没有特定类型的资产没有意义:

abstract class Asset {
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<AssetGroup> Groups { get; set; }
}
class SpecificAsset1 : Asset {
    public string OneProperty { get; set; }
}
class SpecificAsset2 : Asset {
    public string OtherProperty { get; set; }
}

问题是现在Create()调用抛出一个InvalidOperationException,因为"抽象类的实例不能被创建",这当然是有意义的。

那么,问题是,我如何更新多对多关系而不必从数据库中获取资产?

实体框架:抽象类的多对多关系,无需查询数据库即可修改

您可以使用DbSet<T>的通用Create<T>方法来创建派生实体对象。

var temp1 = context.Assets.Create<SpecificAsset1>();

,然后继续使用temp1作为存根实体,就像你已经做的那样。