在 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
,例如 GroupBy
、let
和 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
Input-Output 结果
{1, 2} -> 201, 202
{1, 2, 9} -> 201
{1, 2, 7} -> 202
{1, 2, 7, 9} -> nothing
说明
使用 GroupBy
,您可以首先根据 TagId
对 AttachmentToTagMappings
进行分组,从而创建两个 groups
,其中一个由 201
并且有三个 attm
成员,其标签 ID 分别为 1, 2, and 9
。另一个 group
的键为 202
,有四个 attm
成员,其标签 ID 分别为 1, 2, 7, and 12
。
使用 let
我们想为每个组创建一个 IEnumerable<int>
grpFileIds
。 grpFileIds
仅包含组的 file ids
接下来,使用Except
我们要省略tagIds
中的所有tagId
,它包含在grpFileIds
中,导致剩余的remFileIds
如果 remFileIds.Count
为零,则表示 tagIds
中的所有项在 grpFields
中都有一对。否则,如果 remFileIds.Count
大于零,意味着至少有一个 tagId
该组没有
Select 组(即 201
、202
等)中 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.
由于未经测试,语法可能不准确。
我有下面的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
,例如 GroupBy
、let
和 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
Input-Output 结果
{1, 2} -> 201, 202
{1, 2, 9} -> 201
{1, 2, 7} -> 202
{1, 2, 7, 9} -> nothing
说明
使用
GroupBy
,您可以首先根据TagId
对AttachmentToTagMappings
进行分组,从而创建两个groups
,其中一个由201
并且有三个attm
成员,其标签 ID 分别为1, 2, and 9
。另一个group
的键为202
,有四个attm
成员,其标签 ID 分别为1, 2, 7, and 12
。使用
let
我们想为每个组创建一个IEnumerable<int>
grpFileIds
。grpFileIds
仅包含组的file ids
接下来,使用
Except
我们要省略tagIds
中的所有tagId
,它包含在grpFileIds
中,导致剩余的remFileIds
如果
remFileIds.Count
为零,则表示tagIds
中的所有项在grpFields
中都有一对。否则,如果remFileIds.Count
大于零,意味着至少有一个tagId
该组没有Select 组(即
201
、202
等)中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.
由于未经测试,语法可能不准确。