加入错误|无法创建仅类型为原语的常量值

时间:2018-08-28 19:11:14

标签: c# entity-framework linq

这是LINQ的新功能。

我的表(TableA)中包含以下数据:

ID  Name      SubmissionNo
1   Jim       A-1
2   Andy      A-2
3   Rick      A-2
4   Mary      A-3
5   Zim       A-4
6   Loren     A-1

然后我需要创建一个查询,该查询将允许我从该表中获取具有重复提交编号的记录。

到目前为止,这是我的解决方案(上下文是数据库上下文):

var duplicates = (from tbl in Context.TableA.AsNoTracking()
                  group tbl by tbl.SubmissionNo into grp
                  select new { count = grp.Count(), submissionNo = grp.Key})
                 .Where(x => x.count > 1)
                 .OrderBy(y => y.submissionNo).ToList();

变量重复然后包含记录:

count  submissionNo
2      A-1
2      A-2

然后我编写主查询,这将允许我从具有重复的SubmitNo的TableA中获取所有记录

var myList = (from tbl in Context.TableA.AsNoTracking()
              join dup in duplicates on tbl.SubmissionNo equals dup.submissionNo
              select new 
              { 
                ID = tbl.ID, 
                Name = tbl.Name, 
                SubmissionNo = tbl.SubmissionNo 
              })
              .ToList();

然后我的myList查询出现错误

无法创建类型为“匿名类型”的常量值。在这种情况下,仅支持基本类型或枚举类型。

我认为必须有一种更好的方法,如上表A所示,我实际上希望得到以下结果:

ID  Name      SubmissionNo
1   Jim       A-1
2   Andy      A-2
3   Rick      A-2
6   Loren     A-1

2 个答案:

答案 0 :(得分:2)

您的第一个查询(略有修改)具有您需要的所有信息:

var myList  = from tbl in Context.TableA.AsNoTracking()
              group tbl by tbl.SubmissionNo into grp
              where grp.Count() > 1
              from item in grp
              select new
              { 
                  count = grp.Count(),
                  submissionNo = grp.Key,
                  item.Name,
              );

模式group into grp - from item in grp是常用的查询模式,用于对项目进行分组,然后再次扁平化,同时与组数据保持联系(例如Count()和{ {1}}。

现在,您不再需要连接,并且不会发生异常。顺便说一句,该异常告诉您EF只能处理具有原始类型(Key等)集合的联接,因为EF必须将整个表达式转换为SQL。对于int之类的丰富对象根本没有翻译。

顺便说一句,可以通过删除重复的TableA来改善查询:

Count()

这将生成一个更有效的SQL语句,其中包含一个var myList = from tbl in Context.TableA.AsNoTracking() group tbl by tbl.SubmissionNo into grp let count = grp.Count() where count > 1 from item in grp select new { count = count, submissionNo = grp.Key, item.Name, ); 而不是两个。

答案 1 :(得分:1)

由于Entity Framework不支持将对象的内存中集合与数据库集合连接在一起,因此通常的解决方法是使用public static void main(String[] args) throws IOException, InterruptedException { Map<String, String> map = new HashMap<>(); map.put("Content-Type", "application/json"); String data = "{\\\"nlquery\\\":\\\"Who is the president of Russia?\\\"}"; String result = new Curl.Builder("http://sda.tech/earl/api/processQuery") .method(Curl.HttpMethod.POST) .headers(map) .data(data) .create() .call(); System.out.println(result); } 进行过滤。

首先,您需要获取ID进行过滤:

Contains

然后更改查询以执行var duplicates = (from tbl in Context.TableA.AsNoTracking() group tbl by tbl.SubmissionNo into grp select new { count = grp.Count(), submissionNo = grp.Key}) .Where(x => x.count > 1) .OrderBy(y => y.submissionNo) .ToList(); var duplicateIds = duplicates.Select(x => x.submissionNo).ToList(); 而不是WHERE...IN

JOIN