我有一个名为对话的表格,列出了同一个对话中的用户。例如:
id | conversation | user
1 | 1 | Bob
2 | 1 | Jane
3 | 2 | Tim
4 | 2 | Lily
5 | 2 | Rick
我有一些用户喜欢这样的列表..
List<string> usernames = new List<string>{"Bob","Jane"};
我现在想要检查用户何时想要与其他用户开始对话,无论他们之前是否曾与其他用户进行对话(仅限于此)。
EG。鲍勃希望与简创建一个新的对话。(我的用户名列表值中有鲍勃和简,以便比较之前是否已进行过对话?)
正如我们看到他们两人已经进行了对话,我想让对话ID属于这两个人。
如果我的列表包含以下数据......
List<string> usernames = new List<string>{"Bob","Jane","Tim"};
这一次,我期待之前没有对话。
我想知道没有对话我可以为他们创建一个新的。
我在Linq尝试这个但到目前为止无法得到任何正确的结果。
提前感谢您的帮助;
答案 0 :(得分:2)
您可以按会话ID进行分组,并将这些群组与您的用户列表进行匹配:
var previousConversations = userConversations
.GroupBy(uc => uc.Conversation)
.Where(g => g.OrderBy(uc => uc.user).Select(uc => uc.user)
.SequenceEqual(usernames.Sort()));
答案 1 :(得分:1)
您可以使用SequenceEqual方法比较2个序列。
var users1 = new List<String> { "Bob", "Jane" };
var users2 = new List<String> { "Bob", "Jane", "Tim" };
var tableData = new List<YourTable>
{
new YourTable {foreignKey = 1, name = "Bob"},
new YourTable {foreignKey = 1, name = "Jane"},
new YourTable {foreignKey = 2, name = "Tim"},
new YourTable {foreignKey = 2, name = "Lily"},
new YourTable {foreignKey = 2, name = "Rick"},
};
var keyFound = (from t in tableData
group t by t.foreignKey into users
where users.Select(u => u.name).SequenceEqual(users1)
select users.Key).FirstOrDefault();
var keyNull = (from t in tableData
group t by t.foreignKey into users
where users.Select(u => u.name).SequenceEqual(users2)
select users.Key).FirstOrDefault();
编辑:
您使用linq作为从数据库获取数据的方法,并非所有操作都以这种方式支持。我们可以做的是在内存中提取选择,然后我们可以再次使用所有操作
根据你的情况,这可能不是一个好主意,通常你想让sql处理所有查询功能,因为他更擅长。
但如果您选择的是一个不那么大的桌子,您可以轻松拉入内存,随意这样做:
var rawData = (from t in tableData
group t by t.foreignKey into users
select users).ToList();
var key = (from d in rawData
where d.Select(u => u.name).SequenceEqual(users2)
select d.Key).FirstOrDefault();
如果另一方面数据太大而你想在sql端执行,我会考虑为此创建一个存储过程。
答案 2 :(得分:0)
您基本上正在执行“这些标记”查询,此处可以回答:
Select items by tag when searching multiple tags
应用于您的问题,它看起来像:
int userCount = myUsers.Count;
List<int> conversationIds = conversationsUsers
.Where(cu => myUsers.Contains(cu.UserName))
.GroupBy(cu => cu.ConversationId)
.Where(g => g.Select(cu => cu.Username).Distinct().Count() == userCount)
.Select(g => g.Key)
(完全)。
好吧,好吧......将用户过滤转移到群组过滤中。
int userCount = myUsers.Count;
List<int> conversationIds = conversationsUsers
.GroupBy(cu => cu.ConversationId)
.Where(g => g.Select(cu => cu.Username).Distinct().Count() == userCount)
.Where(g => g.Select(cu => cu.UserName).All(userName => myUsers.Contains(userName)))
.Select(g => g.Key)
答案 3 :(得分:0)
请检查以下linq。如果任何会话为空,它将导致会话ID(枚举不产生结果)。您可以相应地检查您的条件。
var cust = new List<Table>
{
new Table {Conversation = 1, Id = 1, User = "Bob"},
new Table {Conversation = 1, Id = 2, User = "Jane"},
new Table {Conversation = 2, Id = 3, User = "Tim"},
new Table {Conversation = 2, Id = 4, User = "Lily"},
new Table {Conversation = 2, Id = 5, User = "Rick"}
};
var names = new List<string> { "Rick", "Lily", "Tim" };
var res = from x in cust
group x by x.Conversation
into y
where y.Select(z => z.User).Intersect(names).Count() == names.Count
select y.Key;
答案 4 :(得分:0)
感谢大家的帮助和回答。下面的代码完成了这个技巧并给了我想要的结果。感谢Kristof提供此代码和您的努力。我在第二个查询中附加了order by子句,否则它不会给出正确的结果。希望这可以帮助那些需要类似东西的人。
var users1 = new List<String> { "Bob", "Jane" };
var users2 = new List<String> { "Bob", "Jane", "Tim" };
var tableData = new List<YourTable>
{
new YourTable {foreignKey = 1, name = "Bob"},
new YourTable {foreignKey = 1, name = "Jane"},
new YourTable {foreignKey = 2, name = "Tim"},
new YourTable {foreignKey = 2, name = "Lily"},
new YourTable {foreignKey = 2, name = "Rick"},
};
var rawData = (from t in tableData
group t by t.foreignKey into users
select users).ToList();
var key = (from d in rawData
where d.Select(u => u.name).OrderBy(s=> s).SequenceEqual(users2.OrderBy(s=>s))
select d.Key).FirstOrDefault();