Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在选择列表中使用视图模型时,Linq to实体错误_C#_.net_Linq_Linq To Entities - Fatal编程技术网

C# 在选择列表中使用视图模型时,Linq to实体错误

C# 在选择列表中使用视图模型时,Linq to实体错误,c#,.net,linq,linq-to-entities,C#,.net,Linq,Linq To Entities,我试图创建一个SelectList,方法是在单个视图模型实体中包装一大堆模型实体 我有一个视图模型类: public class ReferenceDocumentSelectionViewModel { public ReferenceDocument Document { get; set; } public int ID { get { return Document.ID; } } public String DisplayText {

我试图创建一个
SelectList
,方法是在单个视图模型实体中包装一大堆模型实体

我有一个视图模型类:

public class ReferenceDocumentSelectionViewModel
{
    public ReferenceDocument Document { get; set; }

    public int ID { get { return Document.ID; } }

    public String DisplayText 
    { 
        get 
        { 
            return Document.DocumentNumber + 
                   Document.Version + 
                   Document.Revision + 
                   Document.Sheet; 
        } 
    }
}
然后我尝试使用lambda表达式创建这些对象的列表:

var docs =  _db.ReferenceDocuments
               .Select(r => new ReferenceDocumentSelectionViewModel() 
               { 
                   Document = r 
               });
在将它们分配到
列表之前,请选择:

ReferenceDocList = new SelectList(docs.OrderBy(r => r.DisplayText), 
                                  "ID", 
                                  "DisplayText");
在我看来,我访问SelectList的方式如下:

@Html.DropDownListFor(model => model.SelectedReferenceDoc, 
                      Model.ReferenceDocList, 
                      "-Select-", 
                      new { id = "ReferenceList" })
其中
model.SelectedReferenceDoc
是另一个视图模型上的整数属性

我原以为这会起作用,但我得到了以下错误:

LINQ to中不支持指定的类型成员“DisplayText” 实体。仅初始值设定项、实体成员和实体导航 支持属性

帮忙


编辑:在进一步调查中,似乎是
docs.OrderBy(r=>r.DisplayText)
导致了问题。如果我去掉它,它就可以正常工作了。知道为什么不允许这样做吗?

因为
DisplayText
不是映射属性,所以EF不知道如何将其转换为SQL。这就是为什么它会给你一个错误

您可以通过首先加载所有元素,在此处使用LINQ对对象进行排序

var docs =  _db.ReferenceDocuments
               .Select(r => new ReferenceDocumentSelectionViewModel() 
               { 
                   Document = r 
               }).ToList();
然后在内存中对它们进行排序

ReferenceDocList = new SelectList(docs.OrderBy(r => r.DisplayText), 
                                  "ID", 
                                  "DisplayText");
或按每个属性排序

var docs =  _db.ReferenceDocuments
               .OrderBy(r => r.DocumentNumber)
               .ThenBy(r => r.Version)
               .ThenBy(r => r.Revision)
               .ThenBy(r => r.Sheet)
               .Select(r => new ReferenceDocumentSelectionViewModel() 
               { 
                   Document = r 
               });

ReferenceDocList = new SelectList(docs, 
                                  "ID", 
                                  "DisplayText");
这种排序方式将在数据库中进行,比在内存中进行排序效率更高


因此,首选第二个选项。

因为
DisplayText
不是映射属性,EF不知道如何将其转换为SQL。这就是为什么它会给你一个错误

您可以通过首先加载所有元素,在此处使用LINQ对对象进行排序

var docs =  _db.ReferenceDocuments
               .Select(r => new ReferenceDocumentSelectionViewModel() 
               { 
                   Document = r 
               }).ToList();
然后在内存中对它们进行排序

ReferenceDocList = new SelectList(docs.OrderBy(r => r.DisplayText), 
                                  "ID", 
                                  "DisplayText");
或按每个属性排序

var docs =  _db.ReferenceDocuments
               .OrderBy(r => r.DocumentNumber)
               .ThenBy(r => r.Version)
               .ThenBy(r => r.Revision)
               .ThenBy(r => r.Sheet)
               .Select(r => new ReferenceDocumentSelectionViewModel() 
               { 
                   Document = r 
               });

ReferenceDocList = new SelectList(docs, 
                                  "ID", 
                                  "DisplayText");
这种排序方式将在数据库中进行,比在内存中进行排序效率更高


因此,第二个选项是首选的。

另一个选项是.AsEnumerable(),太好了,谢谢您的解决方案!你能解释一下为什么这样做吗?第一个选项和第二个选项哪个更有效?之所以需要它,是因为传递到
DropDownListFor
的数据仍然是
IQueryable
。在该上下文中执行的任何排序都将尝试转换为SQL。因此,按
DisplayText
排序将不起作用,因为该值仅通过C#code导出。仅按数据库列排序是一种解决方法,或者通过
AsEnumerable
转换为普通的
IEnumerable
是另一种方法(后者允许CLR对数据而不是数据库进行排序)。奇妙的Eranga,正是我所寻找的答案。谢谢你的评论@Jacob。另一个选择是.AsEnumerable()太好了,谢谢你的解决方案!你能解释一下为什么这样做吗?第一个选项和第二个选项哪个更有效?之所以需要它,是因为传递到
DropDownListFor
的数据仍然是
IQueryable
。在该上下文中执行的任何排序都将尝试转换为SQL。因此,按
DisplayText
排序将不起作用,因为该值仅通过C#code导出。仅按数据库列排序是一种解决方法,或者通过
AsEnumerable
转换为普通的
IEnumerable
是另一种方法(后者允许CLR对数据而不是数据库进行排序)。奇妙的Eranga,正是我所寻找的答案。谢谢你的评论@Jacob。