У меня есть две сущности:
public class Child
{
[Key]
public string Id { get; set; }
public List<Parent> Parents { get; set; }
}
public class Parent
{
[Key]
public string Id { get; set; } // If the parent is in Child, the that Id, otherwise a random Guid.
public string ParentId { get; set; } // Id of the parent of this parent.
public string ChildId { get; set; } // Id of the child from the Child class.
public Child Child { get; set; }
}
Контекст БД настроен так:
public class MyContext : DbContext
{
public MyContext(DbContextOptions<MyContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Child>();
builder.Entity<Parent>().HasKey(k => new {k.Id, k.ChildId});
builder.Entity<Parent>()
.HasOne(h => h.Child)
.WithMany(w => w.Parents)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
}
}
Фактические данные таковы, что не каждый родитель находится в таблице Child
но каждый ребенок находится в таблице Child
. Я хочу запросить детей (из таблицы Child
), которые оказались самыми старшими родителями в иерархии родитель-потомок. Например:
/*
* Tree:
* p1(P)--------p2 (P)------r2 (P&C)
* |-----------| |
* | c3 (P&C)
* | |
* | gc1 (C)
* r1 (P&C)---|
* | |
* c1 (C) c2 (C)
*/
Это дерево должно давать r1
и r2
для решения, поскольку они находятся наверху дерева, а также в дочерней таблице. Другими словами, у них нет родителя, который также является ребенком.
До сих пор моя попытка:
using(var ctx = new MyContext(options))
{
var q = ctx.Set<Child>();
var mainQ = q.GroupJoin(q.Where(w => w.Parents.Any()),
o => o.Id,
i => i.Parents.First().ParentId /* For now I'm just trying to handle a single parent.*/,
(o, i) => new { o, i })
.Where(w => !w.i.Any())
.Select(s => s.o)
.Union(q.Where(w => !w.Parents.Any()));
}
Однако этот запрос выдает мне ошибку:
ArgumentException: входная последовательность должна иметь элементы типа Child, но она имеет элементы типа Microsoft.EntityFrameworkCore.Query.Internal.AnonymousObject
Ценить любую помощь.