LINQ到EF怎么了?

时间:2011-03-14 05:21:46

标签: asp.net-mvc linq-to-entities

我正在使用EF。这是我的LINQ查询

 public List<Tuple<int, string>> GetList()
 {
     return (from c in DALContext.MST
             select new Tuple<int, string>(c.CD, c.NAME)).ToList();
 }

当我调用GetList()时,它会抛出异常:LINQ to Entities中只支持无参数构造函数和初始值设定项

相反,当我重写此查询时:

List<Tuple<int, string>> lst = new List<Tuple<int, string>>();
var query= (from c in DALContext.MST
            select new{c.CD, c.NAME});
foreach (var item in query)
{
    lst.Add(new Tuple<int,string>(item.CD,item.NAME));
}
return lst;

它运作正常。我的第一个查询错误???

4 个答案:

答案 0 :(得分:11)

其他答案对于正在发生的事情是正确的,但我没有看到有人提到使代码有效的最佳方式:AsEnumerable()

    public List<Tuple<int, string>> GetList()
    {
        return (from c in DALContext.MST.AsEnumerable()
                select Tuple.Create(c.CD, c.NAME)).ToList();
    }

AsEnumerable方法充当应该转换为SQL并在数据库服务器中执行的代码之间的边界,以及在我们从数据库获得响应之后应该在内存中执行的代码。在表名称之后立即将其写入,以获取MST表中的所有记录,然后运行以下代码,从返回的值创建元组。

我将new Tuple<int, string>更改为Tuple.Create主要是因为我不喜欢输入泛型类型参数。

答案 1 :(得分:6)

LINQ to EF处理查询的方式与LINQ to SQL略有不同。在LINQ to EF中,你不能在LINQ表达式中放置带参数的构造函数,就像你在第一段代码中所做的那样:

from c in DALContext.MST
select new Tuple<int, string>(c.CD, c.NAME)

Tuple的构造函数有两个参数,LINQ to EF中不允许这样做。

原因解释为here

  

在某种程度上,这是一个需要的问题   LINQ to Entities更加明确   关于哪些部分之间的界限   您的查询在服务器上执行   以及在客户端执行的部分。

     

例如,使用LINQ to SQL,它就是   可以写一个LINQ查询   不仅涉及来自服务器的数据   和服务器上的功能   只能执行的函数   客户端并将它们混合在一起   一起。 LINQ to SQL提供程序   然后将尽力解开   事情并执行它的部分   可以在服务器和其他部分上   客户端。这很好,因为它   很容易写任何查询   你想要,如果可能的话   将工作。另一方面,它是   如果你不小心写的话就不那么好了   一个查询,其中唯一的部分可以   在服务器上执行是最多的   返回所有数据的基本内容   在一个或多个表中,然后有   所有过滤都发生在客户端上   (具有非常令人讨厌的性能后果)。

     

使用LINQ to Entities,边界   更明确。当你写一个   针对LINQ to Entities的LINQ查询   IQueryable实现,整个   查询在服务器上执行,如果   查询的某些部分不能   在服务器上执行,然后是   必须使用创建显式边界   像ToQueryable()或   ToList()。执行该查询后   并检索数据,然后就可以了   使用LINQ to Objects进一步细化   您是否选择了查询。这条路   你明确知道你的位置   边界是,而且更容易   追踪绩效问题和   喜欢。其中一个相关的局限   是LINQ中的select语句   实体可以创建匿名类型   或其他类型,只要他们有   默认构造函数和可设置   参数。这最大限度地减少了机会   select语句有主要的   副作用。

答案 2 :(得分:2)

或者你可以写

var query= (from c in DALContext.MST
            select new{c.CD, c.NAME}).ToList().Select(x=>new Tuple(x.CD, x.NAME));

这样做的好处是它只能从数据库中获取您需要的两列。

答案 3 :(得分:1)

你的类需要有一个Linq到EF的无参数构造函数,你必须像这样实例化它:

public List<Tuple<int, string>> GetList()
{
    return (from c in DALContext.MST
            select new Tuple<int, string>(){CD = c.CD, Name = c.NAME}).ToList();
}

编辑:

如果你不能在TUPLE中添加无参数构造函数(这就是Tuple本身不是一个类的情况),那么你就没有选择Linq到EF了,但是这样做是一个两步过程:

public List<Tuple<int, string>> GetList()
{
    List<MST> mstList = (from c in DALContext.MST
                         select c).ToList();

    List<Tuple<int, string>> tupleList = new List<Tuple<int, string>>();

    mstList.foreach(c => tupleList.add(new Tuple(c.CD, c.Name)));

    return tupleList;
}