Linq с DefaultIfEmpty с выбором нового {}

Linq-запрос со значениями по умолчанию. Если в таблице БД эти значения не найдены, то следует взять значения по умолчанию от объекта, а затем в эту таблицу будет добавлена ​​новая строка.

Это должно идти так, но это не работает:

var name_country = (from m in ctx.person
                where (m.name == oPerson.name || m.country == oPerson.country)
                 select new 
                 {
                   m.name, m.country
                 }
                ).DefaultIfEmpty
                               (
                                 oPerson.name,
                                 oPerson.country
                               ).FirstOrDefault();

Как установить эти значения по умолчанию в DefaultIfEmpty???

Новое редактирование: это то, что я хочу сделать одним запросом:

string name = (from m in ctx.person
                where (m.name == oPerson.name || m.country == oPerson.country)
                 select  
                   m.name
                ).DefaultIfEmpty
                               (
                                 oPerson.name,
                               ).FirstOrDefault();
string country = (from m in ctx.person
                where (m.name == oPerson.name || m.country == oPerson.country)
                 select 

                  m.country

                ).DefaultIfEmpty
                               (
                                 oPerson.country
                               ).FirstOrDefault();

3 ответа

Решение
var name_country = (from m in ctx.person
            where (m.name == oPerson.name || m.country == oPerson.country)
             select new 
             {
               m.name, m.country
             }
            ).DefaultIfEmpty
                           (new {
                             oPerson.name,
                             oPerson.country
                           }).First();

Это будет работать до тех пор, пока макет члена идентичен.
Это работает, поскольку анонимные типы вообще анонимны во время выполнения... Пожалуйста, прочтите MSDN-запись для получения дополнительной информации по этой теме:

Если два или более анонимных инициализатора объектов в сборке задают последовательность свойств, которые находятся в одном и том же порядке и имеют одинаковые имена и типы, компилятор обрабатывает объекты как экземпляры одного типа. Они используют одну и ту же информацию о типах, созданную компилятором.

к тому же я предпочел бы пойти на ??...

var name_country = (from m in ctx.person
                    where (m.name == oPerson.name || m.country == oPerson.country)
                    select new 
                    {
                        m.name,
                        m.country
                    }).FirstOrDefault() ?? new {
                        oPerson.name,
                        oPerson.country
                    };

редактировать: вот рабочая скрипка

Если у вас есть Person класс, который выглядит как

public class Person
{
    public string Name { get; set; }
    public string Country { get; set; }
}

То, что вы хотите сделать здесь, это создать новый экземпляр Person (который автоматически устанавливает значения по умолчанию для каждого конкретного типа свойства), если оно не возвращается из вашего запроса к БД, например

var name_country = (from m in ctx.person
                    where (m.name == oPerson.name || m.country == oPerson.country)
                    select new Person
                    {
                        Name = m.name, 
                        Country = m.country
                    }).FirstOrDefault() ?? new { oPerson.name, oPerson.country };

Просто понял, что вы хотите по умолчанию поля из oPerson экземпляр, а не новый экземпляр. Так предполагая oPerson также анонимный объект с точно такой же структурой члена, вы могли бы сделать

var name_country = (from m in ctx.person
                    where (m.name == oPerson.name || m.country == oPerson.country)
                    select new
                    {
                        m.name, 
                        m.country
                    })
                    .DefaultIfEmpty(aPerson)
                    .FirstOrDefault();

Вы ищете эту перегрузку DefaultIfEmpty

public static IEnumerable<TSource> DefaultIfEmpty<TSource>(
    this IEnumerable<TSource> source,
    TSource defaultValue
)

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

Другие вопросы по тегам