2

Generic Repository パターンは初めてです。汎用リポジトリを使ってメソッドを追加、更新、削除、検索するサンプルを作成してみました。私のサンプルコードを見つけて、

汎用リポジトリ インターフェイスとクラス:

public interface IRepository<T> : IDisposable where T : class
{        
    IEnumerable<T> Find(Func<T, bool> predicate);
    void Add(T entity);
    void SaveChanges();
}

public class DataRepository<T> : IRepository<T> where T : class
{
    private ObjectContext _context;
    private IObjectSet<T> _objectSet;

    public DataRepository(ObjectContext context)
    {
       _context = context;
       _objectSet = _context.CreateObjectSet<T>();
    }
    public IEnumerable<T> Find(Func<T, bool> predicate)
    {
        return _objectSet.Where(predicate);
    }
    public void Add(T entity)
    {
       _objectSet.AddObject(entity);
    }
}

そして、私は以下のようにこの方法を使用しました、

DataRepository<tblUser> _tblUser = new DataRepository<tblUser>(new SampleRepositoryEntities());
DataRepository<TestingTable> sampleRepository = new DataRepository<TestingTable>(new SampleRepositoryEntities());
public void GetRecords()
{
    var record1 = sampleRepository.Find(f => f.id == 1).FirstOrDefault();
    var record = _tblUser.Find(f => f.emailid == "karthik@abc.com").FirstOrDefault();
}

SampleRepositoryEntities のテーブル「TestingTable」から Find メソッドを使用してレコードを検索できます。このテーブルには 10 レコード前後のレコードが非常に少ないためです。

しかし、tbluser テーブルから電子メール ID に一致する最初のレコードを見つけようとしました。このテーブルには 50,000 を超えるレコードがあり、この時点で結果を読み込み続けることができず、例外も発生していません。私は何を間違えましたか..誰か私にこれをはっきりさせてもらえますか?

4

1 に答える 1

7

EF で汎用リポジトリを実装するときはいつでも、述語のExpression<Func<T, bool>>代わりに使用します。Func<T, bool>

あなたのケースでは、述語が適用される前に 50,000 件のレコードがすべて取得されていると思います。代わりに、変更するだけです

public IEnumerable<T> Find(Func<T, bool> predicate)

public IEnumerable<T> Find(Expression<Func<T, bool>> predicate)

パフォーマンスが向上するかどうかを確認します。

編集:

@ashutoshraina の指摘をさらに発展させるために、2 つのアプローチをテストして、どのような SQL が生成されているかを確認することにしました。古き良き Northwind データベースを使用して、次のことがわかりました。

クエリWhere(Func< T, bool>)

using (ConsoleApplication2.NorthwindEntities entities =
    new ConsoleApplication2.NorthwindEntities())
{
    Func<Product, bool> f = (p => p.Discontinued);
    var result = entities.Products.Where(f).ToList();
}

次のSQLを生成しました

SELECT  [Extent1].[ProductID] AS [ProductID],
    [Extent1].[ProductName] AS [ProductName],
    [Extent1].[SupplierID] AS [SupplierID],
    [Extent1].[CategoryID] AS [CategoryID], 
    [Extent1].[QuantityPerUnit] AS [QuantityPerUnit],
    [Extent1].[UnitPrice] AS [UnitPrice],
    [Extent1].[UnitsInStock] AS [UnitsInStock],
    [Extent1].[UnitsOnOrder] AS [UnitsOnOrder],
    [Extent1].[ReorderLevel] AS [ReorderLevel],
    [Extent1].[Discontinued] AS [Discontinued]
    FROM [dbo].[Products] AS [Extent1]

クエリWhere(Expression<Func< T, bool>>)

using (ConsoleApplication2.NorthwindEntities entities =
    new ConsoleApplication2.NorthwindEntities())
{
    Expression<Func<Product, bool>> f2 = (p => p.Discontinued);
    var result2 = entities.Products.Where(f2).ToList();
}

次の SQL を生成しました。

SELECT  [Extent1].[ProductID] AS [ProductID],
    [Extent1].[ProductName] AS [ProductName],
    [Extent1].[SupplierID] AS [SupplierID],
    [Extent1].[CategoryID] AS [CategoryID],
    [Extent1].[QuantityPerUnit] AS [QuantityPerUnit],
    [Extent1].[UnitPrice] AS [UnitPrice],
    [Extent1].[UnitsInStock] AS [UnitsInStock],
    [Extent1].[UnitsOnOrder] AS [UnitsOnOrder],
    [Extent1].[ReorderLevel] AS [ReorderLevel],
    [Extent1].[Discontinued] AS [Discontinued]
    FROM [dbo].[Products] AS [Extent1] 
    WHERE [Extent1].[Discontinued] = 1

これは、Expression<Func<T, bool>>アプローチを使用すると、述語を考慮してクエリが生成され、SQL Server がより多くの作業を実行できるようになったことを示していますFunc<T, bool>

于 2013-01-10T06:06:36.667 に答える