简体   繁体   中英

Linq with DefaultIfEmpty with select new {}

Linq query with default values. If in DB Table this values are not found, than default values from object should be taken, and later on new row will be added to this table.

It should go like this, but this does not work:

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();

How to set this Default Values in DefaultIfEmpty???

New Edit: This is what I want to make as one query:

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();
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();

This will work as long as the member-layout is identical .
This works, as anonymous types are anonymous at run-time at all ... Please read the MSDN-entry for more information on this topic:

If two or more anonymous object initializers in an assembly specify a sequence of properties that are in the same order and that have the same names and types, the compiler treats the objects as instances of the same type. They share the same compiler-generated type information.

besides I would rather go for a ?? ...

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
                    };

edit: here's a working fiddle

You are looking for this overload of DefaultIfEmpty

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

You should create a new anonymous object , set it properties, and pass it to the constructor.

Assuming you have a Person class that looks like

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

What you want to do here is create a new instance of Person (which will automatically set the default values for each particular property type) if one isn't returned from your DB query eg

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 };

Just realised that you want to default the fields from the oPerson instance rather than a new instance. So assuming oPerson is also an anonymous object with the exact same member structure, you could do

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM