0

最近、作成したショップに新しい列を追加して、商品を販売できるかどうかを判断する必要がありました。

今事。グローバルwhere句のようなことを行うことは可能ですか、または特定の列に関連するクエリごとに個別に追加する必要がありますか (例Products)? すべてのクエリを修正し、何も見落とさないようにするのは非常に困難です。

私が使用するクエリの例は次のようになりますが、これは非常に基本的なものです。通常、これらのwhereクラスは複数行であり、select別のテーブルの が含まれます。

DataBaseContext db = new DataBaseContext();
// ...

protected bool SomeFunction() {
// ...
    var Products = db.Products.
                       Where(k => k.Active == true).
                       OrderByDescending(k => k.Date);
// ...
}

通常、私はするだろう

var Products = db.Products.Where(k => k.Active == true);
Products = Products.
               Where( ... ).
               Select( ... ).
               OrderBy( ... ).
                  ...
               Take( ... );

しかし、複数の関数があり(dbクラス内のすべての関数に共通です)、SQLサーバー側で条件を記述しようと考えていましたが、残念ながらそれについての知識はありません。

4

2 に答える 2

3

簡単な解決策は、製品の実装を変更することです。

年:

class DataBaseContext 
{ 
     //...
     public DbSet<Product> Products { get; set; }
}

新しい:

class DataBaseContext
{
     //...
     public IQueryable<Product> Products
     {
         get
         {
             return this.Set<Product>().Where(pr => pr.IsActive == true);
         }
     }
}

ただし、アクティブ化できるすべてのタイプのアイテムに対してこれを行う必要があるため、これはあまり堅牢ではなく、メンテナンスも容易ではありません。また、呼び出されるタイプ DbSet の 2 番目のプロパティを作成しAllProducts、クエリが使用されるすべてのポイントをチェックして、アクティブまたは allitems を取得するかどうかを変更する必要があります。

または、次のラッパーを作成することもできますDbContext

interface IMyContext {
    void SaveChanges();
    IQueryable<T> Set<T>() where T: class
    IQUeryable<T> GetActiveItems<T>() where T : SomeBaseClassWithActiveProperty
}

public class MyContext : IMyContext {
    DataBaseContext _underylingContext = new DataBaseContext();

    //... save changes implementation etc   

    public IQueryable<T> Set<T>() 
           where T : class 
    {
           return _underlyingContext.Set<T>();
    }

    public IQueryable<T> GetActiveItems<T>() 
           where T : SomeBaseClassWithActiveProperty
    {
          return this.Set<T>().Where(item => item.IsActive == true);
    }
}

次に、それを使用する場合:

 MyContext context = new MyContext();

 var activeProducts = from p in context.GetActiveItems<Product>()
                      order p  by p.Date //... or whatever;


 var allProducts = from p in context.Set<Product>() //....

いずれにせよ、Product DbSet へのすべての呼び出しをチェックして、アクティブなアイテムのみが必要なのか、すべてのアイテムが必要なのかを検証する必要があります。

于 2013-07-07T20:38:33.520 に答える
0

次の 2 つの手順を使用して、データベース内でこれを行うことができます。

(1) 既存のテーブルの名前を別の名前に変更します。

(2) 既存のテーブルの名前でビューを作成します。

create view <tablename> as
    select *
    from <newtablename>
    where <your condition is true>;

(おそらく、を使用する代わりに、すべての列を一覧表示する必要があります*。)

これで、すべてのクエリでベース テーブルの代わりにビューが使用されるようになります。

ところで、データベースの API を設計するときは、すべてのアクセスをビューから行うことをお勧めします。これにより、API が配置された後にこのような変更が可能になります。

于 2013-07-07T20:54:43.627 に答える