【问题标题】:System.NotSupportedException With compiled LINQ QuerySystem.NotSupportedException 与编译的 LINQ 查询
【发布时间】:2016-08-12 04:57:45
【问题描述】:

我有一个查询数据库的 LINQ 查询(我正在使用 LINQ to SQL)。该查询作为一个独立的查询运行良好,但是当我将它放入已编译的查询时,调用它时出现错误。

错误,

抛出异常:'System.NotSupportedException' in System.Data.Linq.dll 附加信息:成员 'StaffManager.Employee.Key' 没有转换为 SQL 支持。

这是我一直在使用并且有效的查询。

    public static ObservableCollection<Employee> EmployeesInSection(DatabaseDataContext database, string section)
    {
        return new ObservableCollection<Employee>(database.Staff_Time_TBLs
            .Where(staff => staff.Section_Data == section)
            .Select(staff => new Employee(staff.Staff_No ?? -1,
                staff.Staff_Name_First, staff.Staff_Name_Second))
            .ToList()
            .GroupBy(staff => staff.Key)
            .Select(staff => staff.First())
            .OrderBy(staff => staff.Key)
            .ToList());
    }

这是Employee class Key 似乎有问题的Employee class

public class Employee
    {
        public int Key { get; set; }
        public string FirstName { get; set; }
        public string SecondName { get; set; }
        public string FullName => FirstName + " " + SecondName;

        public Employee(int key, string first = null, string second = null)
        {
            Key = key;
            FirstName = first;
            SecondName = second;
        }
    }  

这是编译好的查询和调用查询的方法,

public static class CompiledQueries
    {
        public static Func<DatabaseDataContext, string, IEnumerable<Employee>>        
            sectionEmployess = CompiledQuery.Compile((DatabaseDataContext database, string section) =>
                                 database.Staff_Data_TBLs.Where(staff => staff.Section_Data == section)
                                 .Select(staff => new Employee(staff.Staff_No ?? -1,
                                  staff.Staff_Name_First, staff.Staff_Name_Second))
                                 .ToList()
                                 .GroupBy(staff => staff.Key)
                                 .Select(staff => staff.First())
                                 .OrderBy(staff => staff.Key));                                     

}

还有方法,这里出现错误。

public static ObservableCollection<Employee> EmployeesInSection(DatabaseDataContext database, string section)
        {
            return new ObservableCollection<Employee>
                 (CompiledQueries.sectionEmployess(database, section));
        }

我不知道为什么这在编译查询中不起作用,但在普通的 LINQ 查询中可以正常工作。感谢您抽出宝贵时间提供帮助。

【问题讨论】:

  • 您将查询转换为列表,它不再是可编译的查询。
  • @JeffMercado,你在说这个.ToList() 吗?
  • @JeffMercado,仍然得到完全相同的运行时错误。
  • LINQ 不是 ORM。它不连接到数据库,它只是一种语言。你用的是什么ORM? LINQ转SQL?实体框架? EF 不允许无法映射到 SQL 的查询(例如,如果您在没有 SQL 等效项的情况下进行函数调用)。 L2S 将在内存中加载它可以加载的任何数据,并作为 LINQ to Objects 继续 - 如果它最终加载了一半的数据库,那就太不幸了
  • 您的代码混合了实体框架和 LINQ to Objects,即一个普通的旧内存列表。在分组之前调用ToList() 本身就是一个问题,这意味着您发现您无法执行任何您想要的SQL 分组,而不是修复它,您只是将所有内容加载到内存中。您可以从Staff_Time_TBLs 加载每个员工的最高值,然后最后一个OrderBy 执行ToList().Select 以从查询结果中生成员工

标签: c# linq


【解决方案1】:

这个问题的答案是我试图将CompiledQuery 类用于无法使用的东西。 LINQ 只能在涉及到 SQL 的情况下使用这个类,而下面的这部分查询没有。

.Select(staff => new Employee(staff.Staff_No ?? -1,
                    staff.Staff_Name_First, staff.Staff_Name_Second))
                .ToList()
                .GroupBy(staff => staff.Key)
                .Select(staff => staff.First())
                .OrderBy(staff => staff.Key)
                .ToList());

所以为了使这个工作,第一部分被放入一个编译查询,

public static class CompiledQueries
    {
        public static Func<DatabaseDataContext, string, IQueryable<Staff_Time_TBL>>
             sectionEmployess = CompiledQuery.Compile((DatabaseDataContext database, string section) =>
                  database.Staff_Time_TBLs.Where(staff => staff.Section_Data == section));
    }

比在方法中调用已编译的查询并将 LINQ 的第二部分集成到该方法中。

对于任何感兴趣的人,最初我认为这是一个足够复杂的查询,值得尝试CompiledQuery,其最终目标是提高应用程序的性能。但是,由于CompiledQuery 部分非常简单,最终我收获甚微。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多