在linq to sql中如何应用&&具有可变大小或数组的条件

时间:2016-01-19 14:49:28

标签: c# linq linq-to-sql

我有下表AttachmentToTagMappings

enter image description here

我有一个包含一些标签ID的数组,如下所示,每次执行时大小都会改变。

int[] tagIds= new int[] {1,2,9}; //again the number of elements can change in every execution for example in next execution it may be {1,2,7,12} because the this time the user is looking for the file(s) which are/is mapped to 1,2,7 and 12

现在我想写一个linq,我可以通过它获取映射到上面的数组tagIds元素的fileId。即在上面的表FileId 201中映射到1,2和9所以检索它但不是202因为它只映射到1和2.

5 个答案:

答案 0 :(得分:1)

<强>解决方案

要解决此问题,我会使用LINQGroupBylet等几个Except

这是我的解决方案:

var grp = context.AttachmentToTagMappings.GroupBy(x => x.TagId);
int[] tagIds = new int[] {1,2,9};
var fileIds = from g in grp
              let grpFileIds = g.Select(y => y.FileId)
              let remFileIds = tagIds.Except(grpFileIds)
              where remFileIds.ToList().Count == 0
              select g.Key;

或者,

int[] tagIds = new int[] {1,2,9};
var fileIds = from attm in context.AttachmentToTagMappings
              group attm by new {attm.TagId} into g
              let grpFileIds = g.Select(y => y.FileId)
              let remFileIds = tagIds.Except(grpFileIds)
              where remFileIds.ToList().Count == 0
              select g.Key;

假设:attm.TagId类型与tagId相同,即int 投入产出结果

{1, 2} -> 201, 202
{1, 2, 9} -> 201
{1, 2, 7} -> 202
{1, 2, 7, 9} -> nothing

<强>解释

  1. 使用GroupBy,您可以先根据AttachmentToTagMappingsTagId进行分组,从而创建两个groups,一个由201标识并且有三个attm标记ID分别为1, 2, and 9的{​​{1}}个成员。另一个group的密钥为202,其中有四个attm成员,其标记ID分别为1, 2, 7, and 12

  2. 使用let我们要为每个组创建IEnumerable<int> grpFileIdsgrpFileIds仅包含论坛file ids

  3. 接下来,使用Except我们要忽略tagId中包含的tagIds中的所有grpFileIds,从而产生剩余的remFileIds

  4. 如果remFileIds.Count为零,则表示tagIds中的所有项目都在grpFields中有一对。否则,如果remFileIds.Count大于零,则表示该组至少有一个tagId

  5. 选择201为零的群组中的所有密钥(202remFileIds.Count等)。

答案 1 :(得分:0)

Contains应该被翻译成SQL中的IN子句,这似乎是你想要的:

where tagIds.Contains(attm.TagId)

答案 2 :(得分:0)

尝试.Contain()

var attachments = from attm in context.AttachmentToTagMappings
             where tagIds.Contains(attm.TagId)
        select new { attm.FileId};

或者您可以使用||代替&&,但我认为.Contains()代码更少;)

答案 3 :(得分:0)

根据我的理解,您需要获取附件的列表,其中 tagId 存在于数组中。

var attachments = from attm in context.AttachmentToTagMappings
     where 
         tagIds.Any(id=>id==attm.TagId)
    select new { attm.FileId};

答案 4 :(得分:0)

我认为这就是你要找的东西:

var ids = {1, 2, 3};

var files = context.Files.Where(file => ids.Contains(file.TagId));
if(!ids.AsEnumerable().Except(files.Select(f => f.TagId).AsEnumerable()).Any()){
    return files;
}
return null;

选择所有文件并检查是否有任何与文件中的ID不匹配的ID并返回文件列表。如果没有,则返回null。

语法可能不准确,因为未经测试。