C# 在LINQ中使用投影代替Find()

C# 在LINQ中使用投影代替Find(),c#,asp.net-mvc,linq,C#,Asp.net Mvc,Linq,MVC和LINQ相对较新 在LINQ/EF中使用内置方法通常不适合我,因为我需要使用多个表并创建到新类型的投影以获得所需的数据 当返回iEnumerable时,我可以毫无问题地执行此操作。我的视图需要一个iEnumerable,而我的LINQ查询正好提供了这一点 然而,当我试图替换Find()方法以返回单个记录时,我遇到了一个问题 我的投影与返回多条记录的投影相同,但我添加了where子句以将返回限制为单个记录(使用唯一ID) 我已经改变了我的观点,以期待和对象的类型,我投射到,但这是我能得到的

MVC和LINQ相对较新

在LINQ/EF中使用内置方法通常不适合我,因为我需要使用多个表并创建到新类型的投影以获得所需的数据

当返回iEnumerable时,我可以毫无问题地执行此操作。我的视图需要一个iEnumerable,而我的LINQ查询正好提供了这一点

然而,当我试图替换Find()方法以返回单个记录时,我遇到了一个问题

我的投影与返回多条记录的投影相同,但我添加了where子句以将返回限制为单个记录(使用唯一ID)

我已经改变了我的观点,以期待和对象的类型,我投射到,但这是我能得到的

如果我只是按原样返回查询,延迟执行会导致一个问题,因为我实际上是将查询传递给我的视图,而不是结果(如预期的那样)

因此,我试图弄清楚如何(我猜)执行查询并在控制器中获取对象,然后将其传递给视图。我尝试了SingleOrDefault()和类似的“强制”执行,但这会生成一个新的异常(无法创建“System.Object”类型的常量值。在此上下文中仅支持基元类型或枚举类型。)

很明显,我不明白这里发生了什么

        var model =
            (from p in db.t_Protocol
            join pt in db.t_ProtocolType on p.ProtocolTypeId equals pt.ProtocolTypeID
            where p.ProtocolId.Equals(id)
            select new ProtocolView
            {
                ProtocolId = p.ProtocolId,
                Protocol = p.Protocol,
                ProtocolType = pt.ProtocolType,
                IsAdmission = p.IsAdmission,
                IsReleased = p.IsReleased
            })
            ;
我的观点是:
@model ECM.Models.ProtocolView

首先说明您的视图需要
@model ECM.Models.ProtocolView
说明视图只需要一条记录。如果在设置Var模型时,子表有多条记录,则无论父表只有1条记录,您的投影都会将n条记录强制放入模型中。为了让视图期望IEnumerable,您需要将视图声明更改为
@model IEnumerable
,如果确实需要先执行查找-使用IQueryable,则它们会将结果返回为IEnumerable,因为IEnumerable上的有效负载小于IQueryable上的iQueryYou似乎有两个问题。使用
FirstOrDefault
获取单个记录。如果您得到一个异常,那么您的查询有问题-很可能是
p.ProtocolId.Equals(id)
条件。尝试将其替换为
p.ProtocolId==iid
。问题在于where子句(
p.ProtocolId.Equals(id)
)显然与==运算符的作用不同。非常感谢。谢谢你的回复。正如我最初的帖子所说,我的视图需要一个对象。解决方案张贴在上面。