我有4个使用EntityFramework的查询,它们在拖车/卡车/汽车/工厂上运行,由于结果量大,我需要先将它们连接在一起再执行。
所有4个实体都继承自Asset类型。
这是我要执行的代码以及各种不同的代码:
var truckModels = await truckService.GetAll();
var trailerModels = await trailerService.GetAll();
var companyCarModels = await companyCarService.GetAll();
var plantModels = await plantService.GetAll();
没有任何内容:
assetModels = truckModels.Cast<Asset>()
.Union(trailerModels)
.Union(companyCarModels)
.Union(plantModels);
使用Cast:
assetModels = truckModels.Cast<Asset>()
.Union(trailerModels.Cast<Asset>())
.Union(companyCarModels.Cast<Asset>())
.Union(plantModels.Cast<Asset>());
具有AsEnumerable:
assetModels = truckModels.Cast<Asset>()
.Union(trailerModels.AsEnumerable())
.Union(companyCarModels.AsEnumerable())
.Union(plantModels.AsEnumerable());
使用Cast和AsEnumerable:
assetModels = truckModels.Cast<Asset>()
.Union(trailerModels.Cast<Asset>().AsEnumerable())
.Union(companyCarModels.Cast<Asset>().AsEnumerable())
.Union(plantModels.Cast<Asset>().AsEnumerable());
但是我在所有版本上都遇到以下错误:
“此方法支持LINQ to Entities基础结构,不能直接在您的代码中使用。”
at System.Data.Entity.Core.Objects.ObjectQuery`1.MergeAs(MergeOption mergeOption) at lambda_method(Closure ) at System.Linq.EnumerableExecutor`1.Execute() at System.Linq.EnumerableQuery`1.System.Linq.IQueryProvider.Execute[S](Expression expression) at Kendo.Mvc.Extensions.QueryableExtensions.Count(IQueryable source) at Kendo.Mvc.Extensions.QueryableExtensions.CreateDataSourceResult[TModel,TResult](IQueryable queryable, DataSourceRequest request, ModelStateDictionary modelState, Func`2 selector) at Kendo.Mvc.Extensions.QueryableExtensions.<>c__DisplayClass10.<ToDataSourceResultAsync>b__f() at System.Threading.Tasks.Task`1.InnerInvoke() at System.Threading.Tasks.Task.Execute() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at Viper.Web.Areas.Assets.Controllers.AllController.<GetAssets>d__7.MoveNext() in C:\Repositories\ViperRepo\Viper\Viper.Web\Areas\Assets\Controllers\AllController.cs:line 90
有什么想法吗?我以为您可以合并IQueryable ...
答案 0 :(得分:1)
什么是.GetAll()
。在我看来,您有一个意外的Closure,无法将其转换为EntityFramework操作。
EntityFramework不知道TruckService
和TrailerService
是什么。
如果分解Linq表达式,您会发现您有一个类似
的元素Expression.Lambda(
methodinfo(TruckService.GetAll)
Expression.Parameter(typeof(TruckService))
)
实体框架不知道应该将其简化为
Expression.Lambda(
Expression.Call(
methodInfo(DbContext.DbSet<Truck>),
Expression.Parameter(typeof(AssetDbContext))
)
)
您在这里有一些选择。
但是,每个AssetService中的DbContext显然不是相同的DbContext,这是它参与同一查询所必需的。