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);    

Соответствие применимо к отдельному объекту, Не уверен, что применяется равный перечислимых объектов

Другие вопросы по тегам