哪个设计模式用于过滤查询? C#
我有一个数据库表与产品列表(服装).产品属于不同类别的商品.
样品类别:上衣,底裤,鞋子 样品商店:gap.com,macys.com,target.com 我的客户可以通过以下方式请求过滤产品: >所有产品(无过滤器) 现在我在“产品”类中有一个方法,返回的产品取决于用户请求的过滤器类型.我使用FilterBy枚举来确定需要返回哪些产品. 例如,如果用户想要查看“顶部”类别中的所有产品,我称之为此功能: Products.GetProducts(FilterBy.Category,"tops",""); 我有最后一个参数为空,因为它是包含“存储”过滤的字符串,但在这种情况下没有存储.但是,如果用户想按类别和存储进行过滤,我可以这样调用方法: Product.GetProducts(FilterBy.CategoryAndStore,"macys.com"); 我的问题是,做什么更好的方法?我刚刚了解了策略设计模式.我可以用更好的(更容易扩展和更容易维护)的方法来做到这一点吗? 我问这个问题的原因是因为我认为这是一个很常见的问题,人们一再解决(以各种方式过滤产品) 解决方法
根据埃里克·埃文的“域驱动器设计”,您需要规格模式.这样的东西
public interface ISpecification<T> { bool Matches(T instance); string GetSql(); } public class ProductCategoryNameSpecification : ISpecification<Product> { readonly string CategoryName; public ProductCategoryNameSpecification(string categoryName) { CategoryName = categoryName; } public bool Matches(Product instance) { return instance.Category.Name == CategoryName; } public string GetSql() { return "CategoryName like '" + { escaped CategoryName } + "'"; } } 现在可以使用规格调用您的存储库 var specifications = new List<ISpecification<Product>>(); specifications.Add( new ProductCategoryNameSpecification("Tops")); specifications.Add( new ProductColorSpecification("Blue")); var products = ProductRepository.GetBySpecifications(specifications); 您还可以创建一个通用的CompositeSpecification类,它将包含子规范以及应用于哪个逻辑运算符的指示符AND / OR 我会更倾向于结合LINQ表达式. 更新 – LINQ在运行时的示例 var product = Expression.Parameter(typeof(Product),"product"); var categoryNameExpression = Expression.Equal( Expression.Property(product,"CategoryName"),Expression.Constant("Tops")); 你可以像这样添加一个“和” var colorExpression = Expression.Equal( Expression.Property(product,"Color"),Expression.Constant("Red")); var andExpression = Expression.And(categoryNameExpression,colorExpression); 最后,您可以将此表达式转换为谓词,然后执行它… var predicate = (Func<Product,bool>)Expression.Lambda(andExpression,product).Compile(); var query = Enumerable.Where(YourDataContext.Products,predicate); foreach(Product currentProduct in query) meh(currentProduct); 可能不会编译,因为我已经直接输入到浏览器,但我相信它是一般的正确. 另一个更新:-) List<Product> products = new List<Product>(); products.Add(new Product { CategoryName = "Tops",Color = "Red" }); products.Add(new Product { CategoryName = "Tops",Color = "Gree" }); products.Add(new Product { CategoryName = "Trousers",Color = "Red" }); var query = (IEnumerable<Product>)products; query = query.Where(p => p.CategoryName == "Tops"); query = query.Where(p => p.Color == "Red"); foreach (Product p in query) Console.WriteLine(p.CategoryName + " / " + p.Color); Console.ReadLine(); 在这种情况下,您将在内存中进行评估,因为源是一个列表,但如果您的源是一个支持Linq2SQL的数据上下文,我认为这将使用SQL进行评估. 您仍然可以使用规范模式,以使您的概念明确. public class Specification<T> { IEnumerable<T> AppendToQuery(IEnumerable<T> query); } 这两种方法之间的主要区别在于,后者基于显式属性构建了一个已知的查询,而第一个可以用于构建任何结构的查询(例如,从XML完全构建查询). 这应该足以让你开始:-) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 使用Ruby中的SCP / SSH和Amazon EC2实例中的pem文件
- SetValue in c#
- 详解C++的String类的字符串分割实现
- Swift报错解决" 'try' and the error is no
- ruby-on-rails – 如何在单选按钮标记中传递对象?
- oracle – SQL小提琴输出错误
- 深入分析C语言分解质因数的实现方法
- objective-c – 是否可以在NSPredicate中使用嵌套的SUBQUER
- 解决:Flash Buider 4.6与Chrome调试console出不来信息(将
- 通用权限管理组件支持SqLite,感谢完善者岩子(250952377)