Справка по LINQ to SQL - общие значения - PullRequest
3 голосов
/ 29 сентября 2011
userkey     keyboardkey     keypressed
----------------------------------------
u1          kb1             A
u1          kb1             B  
u1          kb2             C
u2          kb1             A
u2          kb1             B
u3          kb1             A
u3          kb1             B
u3          kb1             D  
u4          kb1             E  

Как я могу написать запрос linq to sql, чтобы получить только общее нажатие клавиши.

Например, найдите общее нажатие клавиш, когда учетная запись пользователя находится в (u1, u2, u3) и клавиатура = kb1. Это даст вывод как список, содержащий A, B.

И найдите общее нажатие клавиш, когда учетная запись пользователя находится в (u1, u2, u3, u4) и клавиатура = kb1, тогда она ничего не должна возвращать.

Спасибо.

Ответы [ 3 ]

3 голосов
/ 29 сентября 2011

Примерно так должно работать:

var commonKeysPressed = db.keys
                          .Where(k => userKeyList.Contains(k.userkey) 
                                 && k.keyboardkey == someKeyboardkey)
                          .GroupBy(k => k.keypressed)
                          .Where( g => g.Select( x=> x.userkey).Distinct().Count() == userCount)
                          .Select(g => g.Key)
                          .ToList();

Для этого необходимо:

  1. keys, чтобы быть рассматриваемой таблицей SQL
  2. userKeyList - массив учетных записей пользователей, т. Е. Строковый массив - в вашем примере (u1, u2, u3)
  3. someKeyboardkey, чтобы быть некоторым значением клавиши клавиатуры, в вашем примере kb1.
  4. userCount количество пользователей в массиве userKeyList (userKeyList.Length)
1 голос
/ 29 сентября 2011

Это работает для меня:

var users = new [] { "u1", "u2", "u3", };

var common = users
    .GroupJoin(
        values.Where(v => v.keyboardkey == "kb1"),
        u => u,
        v => v.userkey,
        (u, vs) => vs.Select(v => v.keypressed))
    .Aggregate(
        (zs, z) => zs.Intersect(z));

Я проверил это в LINQPad на базе данных MySQL, и оно работало нормально.

0 голосов
/ 29 сентября 2011

Ни одной строки LINQ, но это лучшее, что я мог придумать:

private List<String> GetCommonKeys(List<a> input, string[] users, string[] keyboardkeys)
{
    var result = input.Where(c => users.Contains(c.userkey) && keyboardkeys.Contains(c.keyboardkey)).GroupBy (c => c.userkey);
    var returnList = result.First().Select(c => c.keypressed);
    foreach (var ls in result)
    {
        returnList = returnList.Intersect(ls.Select(t => t.keypressed));
    }
    return returnList.ToList();
}

struct a {
    public String userkey;
    public String keyboardkey;
    public String keypressed;
}

Редактировать: как расширение:

public static class myExtensions
{
    public static IEnumerable<TSelectType> SelectCommon<TSourceType, TSelectType>(this IEnumerable<IGrouping<TSelectType, TSourceType>> source, Func<TSourceType, TSelectType> action)
    {
        var firstResult = source.FirstOrDefault();
        if(firstResult == null)
            return new List<TSelectType>();

        var returnCollection = firstResult.Select(action);

        foreach(var ls in source)
            returnCollection = returnCollection.Intersect(ls.Select(action));

        return returnCollection;
    }
}

Используется так:

var res = lst.Where(c => new[] {"u1", "u2", "u3"}.Contains(c.userkey) && c.keyboardkey == "kb1").GroupBy (c => c.userkey).SelectCommon(c => c.keypressed);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...