MicroRuleEngine
MicroRuleEngine copied to clipboard
MRE.ToExpression throws exception
I am trying to get the following to work:
var rule = Rule.Create("Description", "Contains", "Do");
var expression = MRE.ToExpression<T>(rule);
var retVal = records.AsQueryable()
.Where(expression)
.ToList();
where records
is a collection of T
having a property named Description
.
When I run the above code MRE.ToExpression<T>(rule)
throws an InvalidOperationException
with the message: No method 'Contains' on type 'System.String' is compatible with the supplied arguments.'
exception.
Also found out that the following will throw the same exception when trying to compile the rule:
var rule = Rule.Create("Description", "Contains", "Do");
var compiledRule = new MRE().CompileRule<T>(rule);
var retVal = records.AsQueryable()
.Where(r => compiledRule(r))
.ToList();
What the rule is actually trying to produce is code similar to :
if(rec.Description.Contains() == "Do")
Which, of course, is not what you want. I may be able to make Contains() a special case to have that work, but in the general case, you need to may the "Do" the "Inputs" property.
Here's the code I used to diagnose this:
[TestMethod]
public void ToExpressionTest()
{
var records = new HasDescription[] {new HasDescription {Description = "Cat"}, new HasDescription { Description = "Dog" } };
//var rule = Rule.Create("Description","Create" , "Do");
var rule = new Rule {MemberName = "Description", Operator = "Contains", Inputs = new List<object> { "Do" } };
var expression = MRE.ToExpression<HasDescription>(rule);
var retVal = records.AsQueryable()
.Where(expression)
.ToList();
Assert.AreEqual(1, retVal.Count);
Assert.AreEqual("Dog", retVal[0].Description);
}
class HasDescription
{
public string Description { get; set; }
}