首页 > 解决方案 > 值对象弄乱了 Ef 核心 linq 查询

问题描述

我在我的 Person 类中拥有类型

public Name Firstname { get; protected set; }
public Name Lastname { get; protected set; }
public BirthDate BirthDate { get; protected set; }

我像这样配置它们(对于 EF Core 3.1):

builder.OwnsOne(x => x.Firstname).Property(n => n.Value).HasColumnName("Firstname");
builder.OwnsOne(x => x.Lastname).Property(n => n.Value).HasColumnName("Lastname");
builder.OwnsOne(x => x.BirthDate).Property(d => d.Value).HasColumnName("BirthDate");

我有一个不起作用的查询:

from b in context.People 
join p in context.RelatedPeople on b.Id equals p.PersonId into grouping
from p in grouping.DefaultIfEmpty()
group b by new { b.Personalnumber, p.PersonId } into g
select new { g.Key, count = g.Count() };

它只是抛出一个奇怪的异常:

*Unhandled exception. System.InvalidCastException: Unable to cast object of type 'Microsoft.EntityFrameworkCore.Query.SqlExpressions.ColumnExpression' to type 'System.Linq.Expressions.ConstantExpression'.
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.RelationalProjectionBindingRemovingExpressionVisitor.GetProjectionIndex(ProjectionBindingExpression projectionBindingExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.RelationalProjectionBindingRemovingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.RelationalProjectionBindingRemovingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitBlockExpressions(ExpressionVisitor visitor, BlockExpression block)
   at System.Linq.Expressions.ExpressionVisitor.VisitBlock(BlockExpression node)
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.RelationalProjectionBindingRemovingExpressionVisitor.Visit(Expression node, IReadOnlyList`1& projectionColumns)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitShapedQueryExpression(ShapedQueryExpression shapedQueryExpression)
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   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__DisplayClass9_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
   at ConsoleApp1.Program.Main(String[] args) in C:\Users\v.lashkhia\source\repos\TaskWebApi\ConsoleApp1\Program.cs:line 30*

如果我更改我的 ef 核心配置并忽略这三个值对象,则查询开始正常工作。

我错过了什么?我对拥有的类型/值对象的配置是否错误?

标签: c#linqentity-framework-core

解决方案


您对拥有类型的配置似乎是正确的。当您忽略拥有的类型时,您是对的,没有问题。如何通过将查询更改为此来解决问题:

from b in context.People select new {b.Id, b.PersonalNumber } into c
join p in context.RelatedPeople on c.Id equals p.PersonId into grouping
from p in grouping.DefaultIfEmpty()
group c by new { c.PersonalNumber, p.PersonId } into g
select new { g.Key, count = g.Count() };

推荐阅读