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

In linq to sql how to apply && condition with a variable size or array

我有下面的tableAttachmentToTagMappings

我有一个数组,其中包含一些标签 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。即在上面 table FileId 201 映射到 1,2 和 9 所以检索它而不是 202 因为它只映射到 1 和 2.

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

where tagIds.Contains(attm.TagId)

试试 .Contain() :

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

或者您可以使用 || 而不是 &&,但我认为 .Contains() 代码越少越好;)

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

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

解决方案

为了解决这个问题,我会使用几个 LINQ,例如 GroupByletExcept

这是我的解决方案:

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 Input-Output 结果

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

说明

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

  2. 使用 let 我们想为每个组创建一个 IEnumerable<int> grpFileIdsgrpFileIds 仅包含组的 file ids

  3. 接下来,使用Except我们要省略tagIds中的所有tagId,它包含在grpFileIds中,导致剩余的remFileIds

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

  5. Select 组(即 201202 等)中 remFileIds.Count 为零的所有键。

我想这就是您要找的:

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;

Select 所有文件并检查是否没有任何 ID 与文件和 return 文件列表中的 ID 不匹配。如果不是那么 return null.

由于未经测试,语法可能不准确。