11

私はEFでCode Firstを使用しています。2 つのエンティティがあるとします。

public class Farm
{
    ....
    public virtual ICollection<Fruit> Fruits {get; set;}
}

public class Fruit
{
    ...

}

私の DbContext は次のようなものです:

public class MyDbContext : DbSet
{
    ....
    private DbSet<Farm> FarmSet{get; set;} 

    public IQueryable<Farm> Farms
    {
        get
        {
            return (from farm in FarmSet where farm.owner == myowner select farm);
        }
    }
}

これを行うのは、各ユーザーが自分のファームのみを表示できるようにするためであり、データベースへのクエリごとに Where を呼び出す必要はありません。

今、私は1つの農場からすべての果物をフィルタリングしたいので、これを試しました(Farmクラスで):

from fruit in Fruits where fruit .... select fruit

しかし、生成されたクエリには where 句が含まれていません。これは非常に重要です。なぜなら、何十万もの行があり、それらすべてを読み込んでオブジェクトの場合にフィルタリングするのは効率的ではないからです。

遅延ロードされたプロパティは、最初にアクセスされたときに満たされますが、すべてのデータを読み取ります。次のようなことをしない限り、フィルターを適用することはできません。

from fruits in db.Fruits where fruit .... select fruit

しかし、Farm には DbContext の知識がないため (そうすべきではないと思います (?))、それはできませんが、すべてのデータを操作する必要がある場合、ナビゲーション プロパティを使用するという目的全体を失うだけです。私の農場に属するものだけではありません。

そう、

  1. 私は何か間違ったことをしていますか/間違った仮定をしていますか?
  2. 実際のクエリに対して生成されるナビゲーション プロパティにフィルターを適用する方法はありますか? (私は多くのデータを扱っています)

読んでくれてありがとう!

4

3 に答える 3

4

最初のモデルのコードに DDD の原則を追加しようとしてしばらく時間を費やしたので、これに別のソリューションを追加することにしました。しばらく探し回った後、以下のような解決策が見つかりました。

public class FruitFarmContext : DbContext
{
    public DbSet<Farm> Farms { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Farm>().HasMany(Farm.FruitsExpression).WithMany();
    }
}

public class Farm
{
    public int Id { get; set; }
    protected virtual ICollection<Fruit> Fruits  { get; set; }
    public static Expression<Func<Farm, ICollection<Fruit>>> FruitsExpression = x => x.Fruits;

    public IEnumerable<Fruit> FilteredFruits
    {
        get
        {
            //Apply any filter you want here on the fruits collection
            return Fruits.Where(x => true);
        }
    }
}

public class Fruit
{
    public int Id { get; set; }

}

ファームのフルーツ コレクションに直接アクセスすることはできませんが、代わりに事前にフィルター処理されたプロパティを通じて公開されます。ここでの妥協点は、マッピングを設定するときにフルーツ コレクションに対処できるようにするために必要な静的式です。オブジェクトの子コレクションへのアクセスを制御したい多くのプロジェクトで、このアプローチを使い始めました。

于 2014-03-06T20:48:14.717 に答える