gpt4 book ai didi

c# - 实体或复杂类型...无法在 LINQ to Entities 查询中构造

转载 作者:太空狗 更新时间:2023-10-29 21:44:21 25 4
gpt4 key购买 nike

为什么一种方法有效而另一种方法无效,因为它们似乎都在做同样的事情,即构建一个实体。那么我的问题是,有没有一种方法可以在 L2E 查询中构建实体,而不必仅使用 Linq 或两者兼而有之?

这很好用...

var queryToList = (from ac in ctx.AuthorisationChecks
where wedNumbers.Contains(ac.WedNo)
orderby ac.WedNo, ac.ExpAuthDate, ac.ActAuthDate
select new AuthorisationCheck
{
Blah = ac.Blah
}).ToList();

model.AuthorisationChecks = queryToList.Select(x => new AuthorisationCheck
{
Blah = x.Blah
}).ToList();

但是,如果我改变...

var queryToList

model.AuthorisationChecks queryToList // Of type List<AuthorisationCheck>

我得到标题中的错误...

The entity or complex type 'Model.AuthorisationCheck' cannot be constructed in a LINQ to Entities query.

编辑:在模型中,这很简单,没什么特别的。

public List<AuthorisationCheck> AuthorisationChecks { get; set; }

编辑 2:稍微整理一下(效果很好)...

model.AuthorisationChecks = (from ac in ctx.AuthorisationChecks
where wedNumbers.Contains(ac.WedNo)
orderby ac.WedNo, ac.ExpAuthDate, ac.ActAuthDate
select ac).ToList()
.Select(x => new AuthorisationCheck
{
Blah = x.Blah
}).ToList();

EDIT2:我的解决方案我对匿名类型方法不满意,因此继续创建了一个简单的模型,其中仅包含我需要在 View 模型中使用的属性。

更改了模型的类型。AuthorisationChecks

来自

List<AuthorisationCheck> // List of Entities

List<AuthorisationCheckModel> // List of models

它允许下面的代码工作,并且在没有分析的情况下它似乎比使用匿名类型快得多(当然我不会两次转换到列表!)。

model.AuthorisationChecks = (from ac in ctx.AuthorisationChecks
where wedNumbers.Contains(ac.WedNo)
orderby ac.WedNo, ac.ExpAuthDate, ac.ActAuthDate
select new AuthorisationCheckModel
{
Blah = x.Blah
}).ToList();

附言我曾经被一位同事(曾经为微软工作)警告过,以这种方式直接使用实体不是一个好主意,也许这是他考虑的原因之一,我也注意到一些奇怪的在其他情况下直接使用实体的行为(主要是腐败)。

最佳答案

注意:我通常使用 lambda 表达式而不是 Fluent API,但根本问题应该是相同的。

我一直注意到 LINQ 无法将 C# 类用于 Select 语句如果原始数据源(即 ctx 为您)通过将您的查询转换为 SQL 来访问>.

换句话说,从数据库中获取某些内容并将其转换为同一链中的自定义类时会出现问题。

LINQ 非常智能,它实际上不会立即执行您的链接调用。它只是在内部构建一个查询,当您实际访问结果(即从内存中检索值)时,它会执行查询。
我认为这也是您遇到此错误的原因,因为 LINQ 将所有内容(包括 Select)转换为 SQL,但由于没有 SQL 方式来表达它而失败。简而言之,LINQ 不能执行半 SQL、半代码的构建查询。它要么全部在 SQL 中,要么全部在代码中。

您通常可以通过先制作 List<> 来确认情况是否如此。数据库表,然后对其运行完全相同的查询。

var myTable = db.AuthorizationCheck.ToList();

var myResult = myTable. //query here

注意:这不是解决方案!
将整个表放在内存中是一种过于密集的解决方法。只是证明数据源在内存中不会出现问题,而在数据库中就会出现错误。

虽然我从来没有找到解决这个问题的统一方法(通常取决于我的代码审阅者的意见,他是否喜欢这个修复)

使用匿名类型,您可以选择您想要的,然后将其转换为正确的类。您可以使用完全相同的字段,使以后的转换更容易理解。

//Simpler query for clarity's sake
var myAnonymousResult = ctx.AuthorizationChecks
.Where(x => x.IsActive)
.Select(x => new { Name = x.Name, IsActive = x.IsActive })
.ToList();

var myCastResult = myAnonymousResult.Select(x => new Check() { Name = x.Name, IsActive = x.IsActive }).ToList();

如果您使用 lambda 表达式而不是 fluent API,您可以调用 .ToList() 应用过滤器但之前调用.Select()方法。这确保当前查询将被执行,从数据库中检索,并放入实际的 List<> 中。在内存中。届时,您可以调用 .Select()陈述而不会遇到同样的问题。

//Simpler query for clarity's sake
var myCastResult = ctx.AuthorizationChecks
.Where(x => x.IsActive)
.ToList()
.Select(x => new Check() { Name = x.Name, IsActive = x.IsActive });

不幸的是,我在这个问题上的经历是轶事。我一直无法正式证实我对这个问题的根本原因的怀疑;但我提到的解决方法应该有效,因为我过去已经多次应用过它们。

如果有人能解释根本原因,我会很想听听的!

关于c# - 实体或复杂类型...无法在 LINQ to Entities 查询中构造,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28985083/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com