NRules: соответствовать коллекции
Я пытаюсь понять BRE NRules и получил несколько примеров работы, но с трудом подобрал коллекцию.
IEnumerable<Order> orders = null;
When()
.Match<IEnumerable<Order>>(o => o.Where(c => c.Cancelled).Count() >= 3)
.Collect<Order>(() => orders, o => o.Cancelled);
Then()
.Do(ctx => orders.ToList().ForEach(o => o.DoSomething()));
По сути, я хочу, чтобы 3 отмененных ордера сделали какое-то действие. Но я не могу найти совпадение для коллекции, отдельные переменные работают.
Программа:
var order3 = new Order(123458, customer, 2, 20.0);
var order4 = new Order(123459, customer, 1, 10.0);
var order5 = new Order(123460, customer, 1, 11.0);
order3.Cancelled = true;
order4.Cancelled = true;
order5.Cancelled = true;
session.Insert(order3);
session.Insert(order4);
session.Insert(order5);
session.Fire();
Что я здесь не так делаю?
3 ответа
В версии 0.3.1 NRules правило будет активировано, когда вы собрали 3 или более отмененных ордера:
IEnumerable<Order> orders = null;
When()
.Collect<Order>(() => orders, o => o.Cancelled)
.Where(x => x.Count() >= 3);
Then()
.Do(ctx => orders.ToList().ForEach(o => o.DoSomething()));
Обновить:
Для потомков, начиная с версии 0.4.x, правильный синтаксис - использовать реактивный LINQ. Соответствие коллекции будет выглядеть так:
IEnumerable<Order> orders = null;
When()
.Query(() => orders, q => q
.Match<Order>(o => o.Cancelled)
.Collect()
.Where(x => x.Count() >= 3));
Then()
.Do(ctx => DoSomething(orders));
В вашем примере это должно быть довольно просто
IEnumerable<Order> orders = null;
When()
.Collect<Order>(() => orders, o => o.Cancelled == true);
Then()
.Do(ctx => orders.ToList().ForEach(o => o.DoSomething()));
Я думаю, что важной частью является o.Cancelled в одиночку без == true. Я знаю этот звук, но почему-то одна только оценка свойства, которая не является выражением (то есть просто свойством), не очень хорошо поддерживается в NRules.
Я столкнулся с этой проблемой, и когда я добавил == true, все стало на свои места.
Как присоединиться к Multiple Collection на основе выражения
IEnumerable<RawMsp> rawMsps = null;
IEnumerable<AsmMasterView> asmMasterViews = null;
IEnumerable<AsmInvestor> asmInvestors = null;
When()
.Match<AsmInvestor>(() => rawMsps)
.Match<AsmInvestor>(() => asmInvestor, i => i.InvestorId.ToString() == rawMsp.INVESTOR_CODE)
.Match<AsmMasterView>(() => asmMasterView, x => x.ChildAssumptionHistId == asmInvestor.AssumptionHistId);
Соответствие применимо к отдельному объекту, Не уверен, что применяется равный перечислимых объектов