【问题标题】:Linq query to fetch DB records corresponding to List of int[2]Linq 查询获取对应于 int[2] 列表的 DB 记录
【发布时间】:2013-09-17 23:21:41
【问题描述】:

我正在尝试使用 Linq to Entity Framework 计算与 List<int[]> 对应的 VALUEs。

  1. 我有一个List<int[]>,其中List 中的每个int[] 的长度为2。
  2. 我有一个 DB 表 VALUES,其中包含 3 列,分别称为 IDPARENTVALUE,其中 List 中的每个 int[](参见 1)可能对应表中的一条记录,0索引为ID,1索引为PARENT*但是有些数组可能与表中的任何现有记录都不对应。

IDPARENT的每个组合对应多个DB记录,VALUEs不同。

需要注意的几点:

  1. 其中一个问题是我不能单独依赖ID - 每个值都是根据IDPARENT 定义/定位的。
  2. 没有一个 int 数组重复,尽管每个索引中的值可能出现在多个数组中,例如

    List<int[]> myList = new List<int[]>();
    myList.add(new int[]{2, 1});
    myList.add(new int[]{3, 1}); //Notice - same "PARENT"
    myList.add(new int[]{4, 1}); //Notice - same "PARENT"
    myList.add(new int[]{3, 1}); //!!!! Cannot exist - already in the List
    

我似乎无法弄清楚如何从VALUES 表中请求与List&lt;int[]&gt; 中的IDPARENT 对相对应的所有VALUEs。

我尝试了几种变体,但总是陷入尝试在 linq 语句中比较数组的陷阱……如果不加载我实际需要的更多信息,我似乎无法破解它。

可能我得到的最接近的是以下行:

var myList = new List<int[]>();
// ... fill the list ...
var res = myContext.VALUES.Where(v => myList.Any(listItem => listItem[0] == v.ID && listItem[1] == v.PARENT));

当然,这行不通因为The LINQ expression node type 'ArrayIndex' is not supported in LINQ to Entities.


@chris 休伯

我试过了,但没有成功。
两件事:

  1. 在您创建“myValues”的地方,我有一个数据库表实体,而不是一个列表。
  2. 由于第 1 点,我使用的是 LINQ to Entities,而不是 LINQ to Object

然后我的代码变成这样:

var q2 = from value in myContext.VALUES where myList.Select(x => new { ID = x.ElementAt(0), Parent = x.ElementAt(1) }).Contains(new { ID = value.ID, Parent = value.PARENT }) select value;

这会在运行时返回以下错误消息:

LINQ to Entities does not recognize the method 'Int32 ElementAt[Int32](System.Collections.Generic.IEnumerable` 1[System.Int32],Int32)' method, and this method cannot be translated into a store expression.

@Ovidiu

我也尝试了您的解决方案,但问题与上述相同:

当我使用 LINQ to Entities 时,有些事情无法执行,在这种情况下 - ToString() 方法“无法识别”。删除 ToString() 方法并尝试简单地使用 Int32 + "|" + In32 会给我一个关于 LINQ to Entities 无法将 Int32 转换为 Object 的其他错误。

【问题讨论】:

    标签: c# entity-framework-4 linq-to-entities


    【解决方案1】:

    使用以下 LINQ 表达式:

                List<int[]> myList = new List<int[]>();
            myList.Add(new int[] { 2, 1 });
            myList.Add(new int[] { 3, 1 }); //Notice - same "PARENT"
            myList.Add(new int[] { 4, 1 }); //Notice - same "PARENT"
            myList.Add(new int[] { 3, 1 }); 
    
            List<int[]> myValues = new List<int[]>();
            myValues.Add(new int[] { 2, 1 , 1});
            myValues.Add(new int[] { 3, 1 , 2}); //Notice - same "PARENT"
            myValues.Add(new int[] { 4, 1 , 3}); //Notice - same "PARENT"
            myValues.Add(new int[] { 3, 1, 4 });
            myValues.Add(new int[] { 3, 2, 4 }); 
    
            var q2 = from value in myValues where myList.Select(x => new { ID = x.ElementAt(0), Parent = x.ElementAt(1) }).Contains(new { ID = value.ElementAt(0), Parent = value.ElementAt(1) }) select value;
            var list = q2.ToList();
    

    【讨论】:

    • 我用我尝试使用您建议的解决方法的结果更新了问题。
    【解决方案2】:

    您可以使用此解决方法:从您的List&lt;int[]&gt; 创建一个新的List&lt;string&gt;,并将表中的值与新列表进行比较。 我没有用 EF 对此进行测试,但它可能会起作用

    List<string> strList = myList.Select(x => x[0].ToString() + "|" + x[1].ToString()).ToList();
    var res = myContext.VALUES.Where(x => strList.Contains(SqlFunctions.StringConvert((double)x.ID).Trim() + "|" + SqlFunctions.StringConvert((double)x.PARENT).Trim()));
    

    【讨论】:

    • 我用我尝试使用您建议的解决方法的结果更新了问题。
    • 找到了 ToString() here 的替代品。而不是x.ID.ToString() 使用SqlFunctions.StringConvert((double)x.ID).Trim()
    • 这对您在 LINQ to Entities 中有用吗?我收到一条错误消息:The specified method 'System.String StringConvert(SystemNullable' 1[System.Double]' on the type 'Sysmte.DataObjects.SqlClient.SqlFunctions' cannot be translated into a LINQ to Entities store expression.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    • 2017-03-17
    • 2023-03-07
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    相关资源
    最近更新 更多