标记为已禁用的项目的全局WHERE子句

时间:2013-07-07 20:18:40

标签: c# .net sql linq

最近,我不得不为我所制作的商店添加新栏目,确定商品是否可以出售。

现在的事情。是否可以执行类似全局where子句的操作,或者我必须为每个查询单独添加,与某个列相关(例如Products)?很难纠正每个查询而不会遗漏任何内容。

我使用的示例查询看起来像这样,但它只是一个非常基本的查询。通常这些where个clasues是多行的,包括来自另一个表的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服务器端编写条件,但遗憾的是我对此一无所知。

2 个答案:

答案 0 :(得分: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);
         }
     }
}

但是,这不是非常强大且易于维护,因为您必须为可以激活的每种类型的项目执行此操作。此外,您需要创建一个名为AllProducts的DbSet类型的第二个属性,然后通过检查使用查询的所有点来确定是否要获取活动或者所有项目。

或者,您可以为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的调用,并验证您是否只需要有效项目或所有项目。

答案 1 :(得分:0)

您可以使用以下两个步骤在数据库中执行此操作:

(1)将现有表格重命名为其他内容。

(2)使用现有表的名称创建视图:

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

(您可能希望列出所有列,而不是使用*。)

现在所有查询都将使用视图而不是基表。

顺便说一句,在为数据库设计API时,最好通过视图进行所有访问。这允许在API到位后进行类似的更改。