对不起,如果这有点抽象。我现在处于发展的早期阶段。
我有两种对象类型:
以下是一个如何运行的简单示例。
以下是预期输出的示例:
Conditions List
Quantity >= 2 Object5 100%
Value < 2 Object2 75%
Category = "Blah" Object4 50%
Quality > 5 Object1 25%
Object3 0%
每个条件中的第一个操作数是属性的名称,而第二个操作数是该属性的值。
我该如何做到这一点?
我的第一个想法是它看起来类似于查询语言。如果它们是数据库表中的记录,我可以为每个条件拼接一个SQL字符串,运行每个查询并计算每个记录ID在查询结果中显示的次数。但这些都是普通的旧C#对象。我还没有决定使用什么来进行对象持久化,所以我现在不想将自己绑定到数据库引擎。有什么建议吗?
答案 0 :(得分:1)
听起来像LINQ就是你想要使用的。特别是,如果最终选择了持久性存储,我会调查LINQ To Objects和LINQ To SQL。
答案 1 :(得分:0)
另外,还有一篇关于how Directly Execute SQL Queries (LINQ to SQL)
的文章Northwnd db = new Northwnd(@"c:\northwnd.mdf");
IEnumerable<Customer> results = db.ExecuteQuery<Customer>
(@"SELECT c1.custid as CustomerID, c2.custName as ContactName
FROM customer1 as c1, customer2 as c2
WHERE c1.custid = c2.custid"
);
答案 2 :(得分:0)
以下是在字符串上使用LINQ-to-Objects的示例实现:
var conditions = new Func<string, bool>[]
{
s => s.Length < 4, // less than 4 characters
s => s.Count(c => c == 'o') > 2, // more than 2 'o's
s => s == "fooo", // is "fooo"
s => s.Contains('b'), // contains 'b'
};
var words = new[] { "foo", "fooo", "foooo", "bar", "barr", "bazooo" };
var query = words.Select(Word => new
{
Word,
Percentage = conditions.Average(c => c(Word) ? 1M : 0M)
})
.Where(p => p.Percentage > 0) // keep words matches some conditions
.OrderByDescending(p => p.Percentage) // order by the percentage
.ThenBy(p => p.Word); // then order in alphabetical order
回想起来,我认为这个例子也可以与LINQ-to-SQL一起使用(对conditions
数组进行一些调整)。
这只是一个简单的例子,但你当然可以进一步扩展这个想法。
答案 3 :(得分:0)
您可以使用Specification pattern的修改版本执行此操作。从一个以百分比表示结果的界面开始:
public interface ISpecification<T>
{
double GetPercentSatisfiedBy(T target);
}
接下来,创建一个适用于任意条件的规范:
public sealed class Specification<T> : ISpecification<T>
{
private readonly Func<T, bool> _predicate;
public Specification(Func<T, bool> predicate)
{
_predicate = predicate;
}
public double GetPercentSatisfiedBy(T target)
{
return _predicate(target) ? 1 : 0;
}
}
现在,创建一个线性组合其他规范结果的规范:
public sealed class CompositeSpecification<T> : ISpecification<T>
{
private readonly IList<ISpecification<T>> _specifications;
public CompositeSpecification(params ISpecification<T>[] specifications)
{
_specifications = specifications.ToList();
}
public double GetPercentSatisfiedBy(T target)
{
return _specifications.Average(
specification => specification.GetPercentSatisfiedBy(target));
}
}
最后,构建一个包含所有所需条件的规范,并将其应用于Foo
个对象列表:
var specification = new CompositeSpecification<Foo>(
new Specification<Foo>(foo => foo.Quantity >= 2),
new Specification<Foo>(foo => foo.Value < 2),
new Specification<Foo>(foo => foo.Category == "Blah"),
new Specification<Foo>(foo => foo.Quality > 5));
var foos = new List<Foo> { ... };
var results =
from foo in foos
let percentSatisfied = specification.GetPercentSatisfiedBy(foo)
orderby percentSatisfied descending
select new
{
Foo = foo,
PercentSatisfied = percentSatisfied
};
此设计支持任意复杂度的规范。