Linq with DefaultIfEmpty with select new {}

时光总嘲笑我的痴心妄想 提交于 2019-12-05 12:26:13
Andreas Niedermair
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 e.g.

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();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!