DbSetのプライマリキーを取得するにはどうすればよいですか?

.net-core c# entity-framework-core

質問

私はNet Core 1.1とEntity Framework Coreを流暢なAPIで使用しています。私はDbSetがConsoleにそのエンティティを表示するための簡単な拡張メソッドを書いています:

public static class DbSetExtension
{
    public static void Show<T>(this DbSet<T> set) where T:class
    {

        WriteLine();
        WriteLine($"Set: {typeof(T).Name} - {set.Count()} objects.");
        WriteLine();

        foreach (var e in set)
        {
            WriteLine(e);
        }

        WriteLine();
        WriteLine();
    }
}

これは動作しますが、エンティティを表示する前にプライマリキーで並べ替えるようにしたいと思います。私がDbContextを持っていたなら、 DbContextようなことをすることで簡単に達成できました。

var entityType = db.Model.FindEntityType(typeof(T));
var primaryKeyName = entityType.FindPrimaryKey().Properties.First().Name;
var set = db.Set<T>();
var orderedEntities = (set.OrderBy(e=> e.GetType().GetProperty(primaryKeyName).GetValue(e,null))).ToList();

DbSetから同じ結果を得る方法はありますか?

受け入れられた回答

このAPIはEntity Frameworkコアインフラストラクチャをサポートしており、コードから直接使用するためのものではありません。このAPIは将来のリリースで変更されるか、または削除される可能性があります。

基本的にDbSet<T>IInfrastructure<IServiceProvider> DbSet<T>実装しているので、 ModelプロパティからModelを取得するためにGetServiceメソッドを介してIDbContextServicesを取得できます。

using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;

...
var model = set.GetService<IDbContextServices>().Model;
var entityType = model.FindEntityType(typeof(T));
var properties = entityType.GetProperties();
var primaryKeyName = entityType.FindPrimaryKey().Properties.First().Name;
var sortedSet = (set.OrderBy(e=> e.GetType().GetProperty(primaryKeyName).GetValue(e,null))).ToList();
...

人気のある回答

私はIvan Stoevの解決策を受け入れました。それは私の質問に対する非常に良い答えです。

しかし、Ivan氏が指摘するように、 GetServiceIDbContextService APIは「 このAPIはEntity Frameworkコアインフラストラクチャをサポートしており、コードから直接使用するためのものではありません 」とマークされています。私のコードでそれらを使用しないでください。

内部とリフレクションを使用しない別のアプローチは、ソートプロパティをパラメータとして受け入れるように拡張メソッドを書き直すことです。これにより柔軟性も向上します。

同じ問題を抱えている他の人には役に立ちそうなので、この代替ソリューションを投稿しています。

using System;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using static System.Console;

public static class DbSetExtension
{
    public static void ShowSortedBy<T,TKey>(this DbSet<T> set, Func<T,TKey> keySelector) where T:class
    {
        var sortedSet = set.OrderBy(x => keySelector(x)).ToList();

        WriteLine();
        WriteLine($"Set: {typeof(T).Name} - {set.Count()} objects.");
        WriteLine();

        foreach (var e in sortedSet)
        {
            WriteLine(e);
        }

        WriteLine();
        WriteLine();

    }
}


Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ