我的数据库上有3个表。
--- ---学生
id - name
--- ---语言
id - lang
--- StudentLanguage ---( Common Table )
id - studentId - langId
学生可以使用更多语言。我想搜索具有int[]
数组值的学生。但不是IN()
- Contains()
,而是and
- &&
运算符,此运算符采用int[]
值。
在sql =
中`select t1.id, t1.name from Student t1 join StudentLanguage t2
ON(t1.id=t2.studentId) where (t2.langId=1 and t2.langId=3 and t2.langId=5);`
那么如何使用Entity Framework进行此查询? (... where new int[] { 1,3,5 }
)
答案 0 :(得分:3)
此代码生成一些笨拙的SQL查询...
int[] ids = new[] { 1, 3, 5 };
var acc = from st in db.Students select st;
foreach (var id in ids)
{
int id1 = id;
var res =
from st in db.Students
from lng in st.Language
where lng.Id == id1
select st;
acc =
from a in acc
join st in res on a.Id equals st.Id
select a;
}
acc.ToList();
... sql查询:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name]
FROM [dbo].[Student] AS [Extent1]
INNER JOIN [dbo].[StudentLanguage] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Student_Id]
INNER JOIN [dbo].[StudentLanguage] AS [Extent3] ON [Extent1].[Id] = [Extent3].[Student_Id]
INNER JOIN [dbo].[StudentLanguage] AS [Extent4] ON [Extent1].[Id] = [Extent4].[Student_Id]
WHERE ([Extent2].[Language_Id] = @p__linq__0)
AND ([Extent3].[Language_Id] = @p__linq__1)
AND ([Extent4].[Language_Id] = @p__linq__2)
答案 1 :(得分:3)
List<int> langIds = new int[] { 1, 3, 5 }.ToList();
var c = langIds.Count;
var res2 = _context.Students
.Where(x => x.StudentLanguages
.Where(l => langIds.Contains(l.langId)).Select(y => y.langId).Distinct().Count() >= c);
结果SQL:
SELECT [t0].[id], [t0].[name]
FROM [dbo].[Student] AS [t0]
WHERE ((
SELECT COUNT(*)
FROM (
SELECT DISTINCT [t1].[langId]
FROM [dbo].[StudentLanguage] AS [t1]
WHERE ([t1].[langId] IN (1, 3, 5)) AND ([t1].[studentId] = [t0].[id])
) AS [t2]
)) >= 3
如果Distinct
理论上可能包含多个重叠的约束StudentLanguages
- StudentId
,请使用LangId
。
答案 2 :(得分:1)
尝试这样的事情......
resultArr = [];
For(int i = 0; i<arr.length; i++) {
var result = db.Student.Where(s=>s.StudentLanguage.langId == arr[i]);
resultArr.append(result);
}
答案 3 :(得分:0)
我尝试搜索如何做到这一点,这就是我的结果:
int[] langIds = new int[] { 1, 3, 5 };
var lang = _context.Languages.Where(x => langIds.Contains(x.id));
var result = _context.Students.Where(x => !lang
.Except(x.StudentLanguages
.Select(y => y.Language)
.Intersect(lang)).Any());
在这里,我使用Except
和Intersect
linqToSQL 扩展方法。
它产生这个SQL语句:
SELECT [t0].[id], [t0].[name]
FROM [dbo].[Student] AS [t0]
WHERE NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM (
SELECT DISTINCT [t1].[id], [t1].[name]
FROM [dbo].[Language] AS [t1]
WHERE (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM (
SELECT DISTINCT [t3].[id], [t3].[name]
FROM [dbo].[StudentLanguage] AS [t2]
INNER JOIN [dbo].[Language] AS [t3] ON [t3].[id] = [t2].[langId]
WHERE (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[Language] AS [t4]
WHERE ([t3].[id] = [t4].[id]) AND ([t4].[id] IN (@p0, @p1, @p2))
)) AND ([t2].[studentId] = [t0].[id])
) AS [t5]
WHERE [t1].[id] = [t5].[id]
))) AND ([t1].[id] IN (@p3, @p4, @p5))
) AS [t6]
))
请注意,我从数据库填充语言。不幸的是您无法在查询中使用本地集合,因为LinqToSQL不知道如何将它们转换为SQL。如果你对本地int数组或任何其他集合做同样的事情,你将得到这个例外:
LINQ To SQL异常:本地序列不能在LINQ to SQL中使用 查询运算符的实现,包含Contains运算符
答案 4 :(得分:0)
fun main(args: Array<String>) {
val s: String? = null
val maybeSubstring = nullableSubstring(s, 0, 1)
val alsoMaybeSubstring = s?.extensionSubstring(0, 1)
我可以这样做。也许var db = new MyDbContext();
var langIds = new[] { 1, 3, 5 };
IEnumerable<Student> student = from st in db.student select st;
foreach (var item in langIds)
{
student = student.Join(db.StudentLanguage.Where(w => w.langId == item),
st => st.studentId,
stMap => stMap.id,
(st, stMap) => new { Student= stMap, StudentLanguage = st})
.Select(x => x.Student).Distinct();
}
可以转为linq,这段代码只能是一行而且有点短。