4

デフォルト値を使用した Linq クエリ。DB テーブルでこの値が見つからない場合は、オブジェクトからデフォルト値を取得する必要があり、後で新しい行がこのテーブルに追加されます。

次のようになるはずですが、これは機能しません。

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 でこのデフォルト値を設定する方法???

新しい編集:これは私が1つのクエリとして作りたいものです:

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

3 に答える 3

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

これは、member-layout が同一である限り機能します。
匿名型は実行時にまったく匿名であるため、これは機能します...このトピックの詳細については、 MSDN エントリをお読みください。

アセンブリ内の 2 つ以上の匿名オブジェクト初期化子が、同じ順序で同じ名前と型を持つ一連のプロパティを指定する場合、コンパイラはそれらのオブジェクトを同じ型のインスタンスとして扱います。これらは、コンパイラによって生成された同じ型情報を共有します。

その上、私はむしろ??...

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

編集:ここに実用的なフィドルがあります

于 2014-08-14T09:41:03.313 に答える
1

このオーバーロードを探していますDefaultIfEmpty

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

新しい匿名オブジェクトを作成し、プロパティを設定して、コンストラクターに渡す必要があります。

于 2014-08-14T09:34:26.750 に答える
1

Person次のようなクラスがあると仮定します

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

ここでやりたいことはPerson、DB クエリから返されない場合に新しいインスタンスを作成することです (特定のプロパティ タイプごとにデフォルト値が自動的に設定されます)。

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();
于 2014-08-14T09:36:25.280 に答える