?: Оператор в запросе LINQ

  • Как использовать оператор ?: в предложении SELECT запроса LINQ? Если это невозможно сделать, как я могу подражать одному? Цель состоит в том, чтобы получить блок CASE в моем предложении select. Как вы могли догадаться, я получаю сообщение об ошибке: Недопустимый декларатор члена анонимного типа. Члены анонимного типа должны быть объявлены с назначением члена, простым именем или доступом к члену.

  • Это правильный или достаточный способ сказать «из внутреннего соединения i на a.ipid=i.id внутреннего соединения u на i.uid=u.id»? Если нет, пожалуйста, предоставьте один. Спасибо.

    var query =
        from a in db.tblActivities
        from i in db.tblIPs
        from u in db.tblUsers 
        select new {
            u.UserName == null
                ? i.Address
                : u.UserName,
            a.Request,
            a.DateTime };
    

person tsilb    schedule 12.11.2008    source источник


Ответы (5)


При создании анонимного типа (что вы делаете с «новым» без указания типа) вы должны указать имя члена для каждого свойства. В вашем примере это будет выглядеть примерно так: (также исправлено ваше соединение)

var query = from a in db.tblActivities
            join i in db.tblIPs on a.ipid equals i.id
            join u in db.tblUsers on i.uid equals u.id
            select new {
               UserName = (u.UserName ?? i.Address),
               Request = a.Request,
               Date = a.DateTime
            };

Вероятно, вы могли бы сделать и имя пользователя по-своему:

UserName = (u.UserName == null) ? i.Address : u.UserName,

но ?? оператор является более кратким. Это похоже на «isnull» в SQL.

person GalacticCowboy    schedule 12.11.2008
comment
Потрясающий. Это было очень близко, и я получил ответ: из a в TblActivities присоединиться к i в TblIPs по a.IPID равно i.ID присоединиться к u в TblUsers по a.UID равно u.ID select new { UserName = (u.UserName ? i.Address), Request = a.Request, Date = a.DateTime } - person tsilb; 12.11.2008
comment
Если вы видите мой пример, вы можете пропустить операторы соединения, используя вместо этого псевдонимы таблиц. - person LeppyR64; 12.11.2008
comment
Без соединений вы только что реализовали декартово соединение (перекрестное произведение). Если бы в каждой таблице было 10 строк, вы бы получили 1000 результатов. Поверьте мне, вы ДЕЙСТВИТЕЛЬНО хотите, чтобы эти соединения были там. - person GalacticCowboy; 12.11.2008
comment
@GalacticCowboy, я совершенно уверен, что ты ошибаешься. Обратите внимание, что предложенный мной запрос должен использовать встроенные отношения FK для соединений. Я не использую db в каждой строке. См. здесь: stackoverflow.com/questions/283103/linq- to-sql-внешние ключи - person LeppyR64; 12.11.2008
comment
@ Джейсон, ты прав, я упустил тот факт, что ты использовал встроенные отношения. Если бы он их использовал (и не уверен, почему он не может...), это сработало бы нормально. Я ответил и в другой вашей теме. - person GalacticCowboy; 12.11.2008
comment
@tslib, это совсем другой вопрос. Вы, безусловно, должны обрабатывать отношения в своей БД, чтобы сохранить свою реляционную целостность. Если вы этого не сделаете, вы столкнетесь с ситуациями, когда данные будут неправильно изменены из другого источника, тогда ваш RE испорчен. - person LeppyR64; 12.11.2008
comment
@ Джейсон, спасибо за ваш вклад; но это для моего личного блога и других источников у него нет. - person tsilb; 13.11.2008

Вы должны использовать ключевое слово соединения и определить отношения между объектами, чтобы сделать правильное внутреннее соединение.

Здесь вы можете найти несколько примеров, я также настоятельно рекомендую вам чтобы получить LinqPad, это действительно ценный инструмент для тестирования ваших запросов, а также очень полезный для изучения, он имеет 200+ примеров.

person Christian C. Salvadó    schedule 12.11.2008

если вы проверяете только значение null, вы также можете использовать ??

string something = null;
string somethingElse = something ?? "default value";

Что касается примеров выше, то правильно делать те, которые идут...

string something = (somethingElse == null ? "If it is true" : "if it is false");

Скобки не требуются, но они помогают в чтении.

person hugoware    schedule 12.11.2008
comment
Ваша логика хороша для стандартных манипуляций со строками, но этот LINQ работает только наполовину, как можно интуитивно ожидать... Та же ошибка. - person tsilb; 12.11.2008
comment
странно... Я использовал это в запросах LINQ раньше... во второй части. - person hugoware; 12.11.2008

Действительно. этот вопрос зависит от конкретной реализации IQueryable, которую вернет ваше выражение linq. Я вижу, что у вас есть db.XXX, поэтому вы используете linq to sql или какой-то linq для хранилища данных? Если это так, конкретная реализация IQueryable должна иметь способ перевести ваше выражение в выражение хранилища. Помимо приведенных выше комментариев, некоторые другие комментарии верны тому, что в анонимном типе вы должны указать имя для каждого члена. Это действительно ваша ошибка.

person user36784    schedule 12.11.2008
comment
db в данном случае является DataContext для моего класса Linq to SQL. - person tsilb; 12.11.2008
comment
Я вижу, это имеет смысл. У вас есть ответ, который вам нужен среди всего этого? - person user36784; 12.11.2008

Я новичок в Linq to SQL, но я уверен, что это будет выглядеть так:

var query =
    from a in db.tblActivities
    from i in a.tblIPs
    from u in i.tblUsers 
    select new
    {
        userName = (u.UserName == null)
            ? i.Address
            : u.UserName,
        a.Request,
        a.DateTime
    };

Оператор if должен быть заключен в круглые скобки, а результат — за их пределами. Что касается соединений, вы следуете по цепочке от одного до многих.

person LeppyR64    schedule 12.11.2008