Eric Evan'un "Domain Drive Design" 'a göre, belirtim desenine ihtiyacınız var. Böyle bir şey
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 } + "'";
}
}
Kişisel depo şimdi de mantıksal operatör bunlara uygulamak üzere alt şartname ve bir gösterge içerecektir genel CompositeSpecification sınıf oluşturabilir
var specifications = new List<ISpecification<Product>>();
specifications.Add(
new ProductCategoryNameSpecification("Tops"));
specifications.Add(
new ProductColorSpecification("Blue"));
var products = ProductRepository.GetBySpecifications(specifications);
özellikleri ile çağrılabilir VE/OR
Yine de LINQ ifadelerini birleştirmeye daha yatkın olurdum.
Güncelleme - Son olarak bir yüklemi içine bu ifadeyi dönüştürebilir ve sonra Çalıştır bir "ve"
var colorExpression = Expression.Equal( Expression.Property(product, "Color"), Expression.Constant("Red")); var andExpression = Expression.And(categoryNameExpression, colorExpression);
şöyle zamanında
var product = Expression.Parameter(typeof(Product), "product");
var categoryNameExpression = Expression.Equal(
Expression.Property(product, "CategoryName"),
Expression.Constant("Tops"));
de LINQ örneği ekleyebilir. ..
var predicate =
(Func<Product, bool>)Expression.Lambda(andExpression, product).Compile();
var query = Enumerable.Where(YourDataContext.Products, predicate);
foreach(Product currentProduct in query)
meh(currentProduct);
Muhtemelen derlemem çünkü ben doğrudan tarayıcıya yazdım, ancak genelde doğru olduğuna inanıyorum.
Diğer bir güncelleme kaynağı bir Liste olduğu için bellekte değerlendirirken olacağını Bu durumda :-)
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();
ama kaynak bence örneğin Linq2SQL desteklenen bir veri bağlamı olsaydı bu, SQL kullanarak değerlendirir.
Kavramlarınızı açık hale getirmek için Spesifikasyon modelini kullanmaya devam edebilirsiniz.
public class Specification<T>
{
IEnumerable<T> AppendToQuery(IEnumerable<T> query);
}
iki yaklaşım arasındaki temel fark, (örneğin XML tamamen bir sorgu yapı olarak ilk bir yapının bir sorgu oluşturmak için kullanılabilir, oysa ikinci, açık özelliklerine göre bilinen bir sorgu inşa edilmiş olmasıdır örneğin.)
Bu burada gitmeden olarak nerede şeyler sadece eklenemez :-)
[Örnek ile Filtre Tasarımı Desen] (http://www.singhajit.com/filter-design-pattern/) –