查询与多种实体类型相关的表

时间:2019-06-24 14:03:41

标签: sql entity-framework

所以目前我的应用程序模型为:

Note -> Thing

(一个注释可能与许多things相关)

thing可以是众多实体(在此示例中,请使用ComputerCar

例如

Note -> Computer
     -> Car

现在,我的模式是

Note -> ComputerNote -> Computer
Note -> CarNote      -> Car

问题在于,由于实体链接位于单独的表中,因此它需要编写新的查询,而不仅仅是在WHERE子句中使用过滤。

理想情况下,在EntityId表上有一个EntityTypeIdNote列,该列将保存相关实体的主键和实体的类型。因此,应用程序逻辑可以查找所有Car车在哪里的x注释,而无需分别查询每种类型,但这将意味着我失去参照完整性。有没有更好的方法,还是我建议的设计可以接受?

实体框架模型的

public partial class Note
{
    public Note()
    {
        NoteComputer = new HashSet<NoteComputer>();
        NoteCar = new HashSet<NoteCar>();
        NoteThing = new HashSet<NoteThing>();
    }

    public int Id { get; set; }
    public string Value { get; set; }
    public string CreatedByUserId { get; set; }
    public DateTime CreatedDateTime { get; set; }

    public ICollection<NoteComputer> NoteComputer { get; set; }
    public ICollection<NoteCar> NoteCar { get; set; }
    public ICollection<NoteThing> NoteThing { get; set; }

}
public partial class NoteCar
{
    public int Id { get; set; }
    public int NoteId { get; set; }
    public int CarId { get; set; }

    public Car Car { get; set; }
    public Note Note { get; set; }
}
public partial class NoteComputer
{
    public int Id { get; set; }
    public int NoteId { get; set; }
    public int ComputerId { get; set; }

    public Computer Computer { get; set; }
    public Note Note { get; set; }
}
public partial class NoteThing
{
    public int Id { get; set; }
    public int NoteId { get; set; }
    public int ThingId { get; set; }

    public Thing Thing { get; set; }
    public Note Note { get; set; }
}

1 个答案:

答案 0 :(得分:0)

由于似乎没有很好的方法在数据库级别处理此问题,因此我发现最好在应用程序级别使用具体的类型数据库模式处理此问题,以产生动态联接。 Enttity Framework Core中的示例:

public GenericEntityProvider 
{
    private readonly IEnumerable<IEntityProvider> _entityProviders;
    private readonly DatabaseContext _context;

    public GenericEntityProvider(IEnumerable<IEntityProvider> entityProviders, DatabaseContext context) 
    {
        _entityProviders = entityProviders;
        _context = context;
    }

    public IEnumerable<Note> Get(Type type, int id) {
        var provider = _entityProviders.GetPredicate(type, id);
        return _context.Notes.Where(provider);
    }

}

public CarNoteProvider : IEntityProvider 
{
    public Expression<Func<Note, bool>> GetPredicate(Type type, int id) 
    {
        return x => x.CarNote.Any(cn => cn.CarId == id);
    }
}