एरिक इवान के "डोमेन ड्राइव डिज़ाइन" के अनुसार आपको विनिर्देश पैटर्न की आवश्यकता है। कुछ इस तरह
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 वर्ग जो उप विनिर्देशों और एक संकेतक जो तार्किक ऑपरेटर के रूप में उन्हें लागू करने के लिए करने के लिए होते हैं बना सकते हैं के साथ कहा जा सकता है और/या
हालांकि मैं LINQ अभिव्यक्तियों को गठबंधन करने के इच्छुक हूं।
अपडेट - क्रम
var product = Expression.Parameter(typeof(Product), "product");
var categoryNameExpression = Expression.Equal(
Expression.Property(product, "CategoryName"),
Expression.Constant("Tops"));
में LINQ का उदाहरण आपको एक "और" इतनी तरह
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 का समर्थन किया था यह एसक्यूएल का उपयोग करके मूल्यांकन करेगा।
आपकी अवधारणाओं को स्पष्ट करने के लिए आप अभी भी विशिष्टता पैटर्न का उपयोग कर सकते हैं।
public class Specification<T>
{
IEnumerable<T> AppendToQuery(IEnumerable<T> query);
}
दो दृष्टिकोण के बीच मुख्य अंतर (जैसे एक्सएमएल से पूरी तरह से एक प्रश्न के निर्माण के रूप में कि बाद, स्पष्ट गुणों के आधार पर एक ज्ञात क्वेरी बनाता है, जबकि पहले एक किसी भी संरचना के एक प्रश्न के निर्माण के लिए इस्तेमाल किया जा सकता है उदाहरण के लिए।)
यह आपको :-)
[उदाहरण के साथ फ़िल्टर डिजाइन पैटर्न] (http://www.singhajit.com/filter-design-pattern/) –