0

最近我不得不为我制作的商店添加一个新列,以确定该商品是否应该可供出售。

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

我使用的示例查询看起来像这样,但它只是一个非常基本的查询。通常这些where子句是多行的,包括select来自另一个表的 s。

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 类型的属性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

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

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

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

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

(您可能想要列出所有列而不是使用*。)

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

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

于 2013-07-07T20:54:43.627 回答