我有一个数据库,其中包含user_id
和tag_id
的表格。我想写一个函数,它需要两个user_id
并返回两个用户共同的tag_id
个。
这些是数据库中的示例行:
User_id Tag_id
1 100
1 101
2 100
3 100
3 101
3 102
我想从我的函数中得到的是,当我调用我的函数getCommonTagIDs(1, 3)
时,它应该返回(100,101)
。到目前为止我所做的是在两个不同的列表中保留与user_id
相关的行,然后使用for循环,返回公共tag_id
。
using (TwitterDataContext database = TwitterDataContext.CreateTwitterDataContextWithNoLock())
{
IEnumerable<Usr_Tag> tags_1 = database.Usr_Tags.Where(u => u.User_id == userID1).ToList();
IEnumerable<Usr_Tag> tags_2 = database.Usr_Tags.Where(u => u.User_id == userID2).ToList();
foreach (var x in tags_1)
{
foreach (var y in tags_2) {
if (x.Tag_id == y.Tag_id) {
var a =database.Hashtags.Where(u => u.Tag_id==x.Tag_id).SingleOrDefault();
Console.WriteLine(a.Tag_val);
}
}
}
}
我想问的是,我不是从数据库中获取所有行并在函数中搜索公共tag_id
,而是希望直接从LINQ数据库获取公共tag_id
通过在数据库端进行计算。如果你能帮助我,我将不胜感激。
这是我写的SQL:
SELECT [Tag_id]
FROM [BitirME].[dbo].[User_Tag]
WHERE USER_ID = '1' AND Tag_id IN (
SELECT [Tag_id]
FROM [BitirME].[dbo].[User_Tag]
where USER_ID = '3')
答案 0 :(得分:2)
你想要的是这两组的“交集”:
var commonTags = database.Usr_Tags.Where(u => u.User_id == userID1).Select(u => u.Tag_id)
.Intersect(database.Usr_Tags.Where(u => u.User_id == userID2).Select(u => u.Tag_id));
瞧,你已经完成了。
或者,稍微清理一下:
public static IQueryable<int> GetUserTags(int userId)
{
return database.Usr_Tags
.Where(u => u.User_id == userId)
.Select(u => u.Tag_id);
}
var commonTags = GetUserTags(userID1).Intersect(GetUserTags(userID2));
答案 1 :(得分:1)
这是一种方法:
int[] users = new int[] {1,3}; // for testing
database.Ustr_Tags.Where(t => users.Contains(t.User_id))
.GroupBy(t => t.Tag_id)
.Where(g => users.All(u => g.Any(gg=>gg.User_id == u))) // all tags where all required users are tagged
.Select(g => g.Key);
这个的一个好处是它可以用于任何数量的用户(不仅仅是2个)。
答案 2 :(得分:0)
如果我做对了,像这样的查询可能是你需要的
var q = from t in database.Usr_Tags
//all Usr_Tags for UserID1
where t.User_Id == userID1 &&
//and there is a User_tag for User_ID2 with same Tag_ID
database.User_Tags.Any(t2=>t2.User_ID==userID2 && t2.Tag_ID==t.Tag_ID)
select t.Tag_Id;
var commonTags = q.ToList();