【问题标题】:How to specify which columns can be returned from linq to sql query如何指定可以从 linq 到 sql 查询返回哪些列
【发布时间】:2010-11-04 04:45:01
【问题描述】:

我试图从 linq 到 sql 查询中只返回几列,但如果我这样做了,它会引发异常:

不允许在查询中显式构造实体类型“InVision.Data.Employee”

代码如下:

return db.Employees.Select(e => new Employee()
       { EmployeeID = e.EmployeeID, FirstName = e.FirstName,
         LastName = e.LastName }).ToList();

如果我返回所有内容,那么它将引发有关循环引用的异常,因为它需要被序列化才能在 javascript 中使用,所以我真的需要限制列...感谢您可以给我解决这个问题的任何提示。

【问题讨论】:

  • 我认为不返回整个 Employee 对象没有任何强有力的论据。性能当然不是其中之一。 Linq 会注意不返回任何关联,除非它们被访问。
  • @cdonner 我想当以下四个条件为真时返回所有列是合适的:A)您的 SQL 实例有 SSD 驱动器,并且 B)有 10GBps 到 SQL SAN 单元的连接, C) 在所有 SQL 服务器和应用程序服务器上拥有两倍的内存,并且 D) 拥有比您知道的更多的 SQL 核心许可证。

标签: sql linq explicit construction


【解决方案1】:

贾斯汀,

此处对该错误的解释: http://devlicio.us/blogs/derik_whittaker/archive/2008/04/25/linq2sql-explicit-construction-of-entity-exception.aspx

您可以做的一件事是创建一个派生自 Employee 的类。

public class EmployeeProxy : Employee
{
}

然后你可以做你的查询:

return db.Employees.Select(e => new EmployeeProxy { EmployeeID=e.EmployeeID, FirstName=e.FirstName, LastName=e.LastName }).ToList();

另一方面,如果您只需要将结果集序列化为javascript,那么您也可以只使用匿名类。这也有效:

return db.Employees.Select(e => new { EmployeeID=e.EmployeeID, FirstName=e.FirstName, LastName=e.LastName }).ToList();

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    基本上,如果您只想要列,请选择这些列。如果您想要员工实体,请选择它。这里没有太多的中间立场。我建议不要为此创建一个新课程。呸!

    这样做:

    return db.Employees
       .Select(e => new { e.EmployeeID, e.FirstName, e.LastName })
       .ToList();
    

    【讨论】:

    • 谢谢,但是该函数返回 List,如果您只是在没有指定 Employee 的情况下执行 new,那么它将无法编译,因为查询将返回 List。我最终找到了解决方案: var query = from e in db.Employees select new { e.EmployeeID, e.LoginName, e.FirstName, e.LastName }; var typedQuery = from e in query.AsEnumerable() select new Employee { EmployeeID = e.EmployeeID, LoginName = e.LoginName, FirstName = e.FirstName, LastName = e.LastName }; return typedQuery.ToList();
    • 那种作品。但我仍然不喜欢它,因为你的函数的调用者很可能期望完整的 Employee 对象,而你没有把它给他。我建议不要做所有这些,而是​​返回 IQueryable 并返回整个 Employee 对象。因为您返回的是 IQueryable 而不是列表,所以执行将推迟到您的调用者,他们可以在他们的方法中选择他们想要的内容...
    • 这个可以动态指定吗,比如用逗号分隔的字符串?
    【解决方案3】:

    因为在我建议使用 View 对象而不是 Linq2Sql 实体来处理这种情况之前,我不得不与 Linq2Sql 和序列化作斗争。这是一个更简单的解决方案:

    return db.Employees
            .Select( e => new EmployeeView() 
            { 
                EmployeeID = e.EmployeeID, 
                FirstName = e.FirstName, 
                LastName = e.LastName 
             }).ToList();
    

    另一种选择是将 Employee 表的新副本拖到 DBML 设计器中,将其命名为 SimpleEmployee 之类的不同名称,删除所有关系并删除所有不需要的列。

    【讨论】:

      猜你喜欢
      • 2013-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-12
      相关资源
      最近更新 更多