Таблица EFCore для каждой иерархии: запрос с базовым типом в дочернем элементе «Не удалось перевести элемент «Родитель» ⇐ C#
-
Anonymous
Таблица EFCore для каждой иерархии: запрос с базовым типом в дочернем элементе «Не удалось перевести элемент «Родитель»
Я пытаюсь написать запрос, подобный следующему, с использованием аналогичной модели. Я думаю, что понимаю проблему, но не смог отредактировать модель таким образом, чтобы не добавлять новые столбцы внешнего ключа в базовую таблицу.
Было бы также знать, почему, когда я добавляю базы в родительскую таблицу, в базовую таблицу добавляются новые столбцы для базы, D1 и D2. Кажется, это наименее ожидаемый результат.
public List Bases {get; set;}
Ошибка:
Unhandled exception. System.InvalidOperationException: The LINQ expression 'DbSet()
.Join(
inner: DbSet(),
outerKeySelector: b => EF.Property(b, "BaseId"),
innerKeySelector: b0 => EF.Property(b0, "ID"),
resultSelector: (o, i) => new TransparentIdentifier(
Outer = o,
Inner = i
))
.Where(b => b.Inner.Parent.ID == 1)' could not be translated. Additional information: Translation of member 'Parent' on entity type 'Base' failed. This commonly occurs when the spec
ified member is unmapped. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutorExpression[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.c__DisplayClass11_0`1.b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteCore[TResult](Expression query, Boolean async, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Program.$(String[] args) in C:\Users\Anthony\RiderProjects\efcore-tph\Program.cs:line 5
at Program.(String[] args)
Запрос:
await context.BaseChildren.Where(x => x.Base.Parent.ID == 1).ToListAsync();
Модель:
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
public class MyContext : DbContext
{
public DbSet Parents { get; set; }
public DbSet D1s { get; set; }
public DbSet D2s { get; set; }
public DbSet BaseChildren { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseNpgsql(@"Host=localhost;Username=postgres;Password=password;Database=mydatabase");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity()
.HasDiscriminator("type")
.HasValue("base")
.HasValue("d1")
.HasValue("d2");
}
}
public class Parent
{
public int ID { get; set; }
public List D1s { get; set; }
public List D2s { get; set; }
}
public abstract class Base
{
public int ID { get; set; }
public string Url { get; set; }
public int ParentId { get; set; }
[ForeignKey(nameof(ParentId))]
public Parent Parent { get; set; }
public List Children { get; set; }
}
public class BaseChild
{
public int ID { get; set; }
public string Property { get; set; }
public int BaseId { get; set; }
[ForeignKey(nameof(BaseId))]
public Base Base { get; set; }
}
public class D1 : Base
{
public string D1Property { get; set; }
}
public class D2 : Base
{
public string D2Property { get; set; }
}
Я пытаюсь написать запрос, подобный следующему, с использованием аналогичной модели. Я думаю, что понимаю проблему, но не смог отредактировать модель таким образом, чтобы не добавлять новые столбцы внешнего ключа в базовую таблицу.
Было бы также знать, почему, когда я добавляю базы в родительскую таблицу, в базовую таблицу добавляются новые столбцы для базы, D1 и D2. Кажется, это наименее ожидаемый результат.
public List Bases {get; set;}
Ошибка:
Unhandled exception. System.InvalidOperationException: The LINQ expression 'DbSet()
.Join(
inner: DbSet(),
outerKeySelector: b => EF.Property(b, "BaseId"),
innerKeySelector: b0 => EF.Property(b0, "ID"),
resultSelector: (o, i) => new TransparentIdentifier(
Outer = o,
Inner = i
))
.Where(b => b.Inner.Parent.ID == 1)' could not be translated. Additional information: Translation of member 'Parent' on entity type 'Base' failed. This commonly occurs when the spec
ified member is unmapped. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutorExpression[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.c__DisplayClass11_0`1.b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteCore[TResult](Expression query, Boolean async, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Program.$(String[] args) in C:\Users\Anthony\RiderProjects\efcore-tph\Program.cs:line 5
at Program.(String[] args)
Запрос:
await context.BaseChildren.Where(x => x.Base.Parent.ID == 1).ToListAsync();
Модель:
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
public class MyContext : DbContext
{
public DbSet Parents { get; set; }
public DbSet D1s { get; set; }
public DbSet D2s { get; set; }
public DbSet BaseChildren { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseNpgsql(@"Host=localhost;Username=postgres;Password=password;Database=mydatabase");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity()
.HasDiscriminator("type")
.HasValue("base")
.HasValue("d1")
.HasValue("d2");
}
}
public class Parent
{
public int ID { get; set; }
public List D1s { get; set; }
public List D2s { get; set; }
}
public abstract class Base
{
public int ID { get; set; }
public string Url { get; set; }
public int ParentId { get; set; }
[ForeignKey(nameof(ParentId))]
public Parent Parent { get; set; }
public List Children { get; set; }
}
public class BaseChild
{
public int ID { get; set; }
public string Property { get; set; }
public int BaseId { get; set; }
[ForeignKey(nameof(BaseId))]
public Base Base { get; set; }
}
public class D1 : Base
{
public string D1Property { get; set; }
}
public class D2 : Base
{
public string D2Property { get; set; }
}