首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在NRULES中实现前向链接的最佳方法

在NRULES中实现前向链接的最佳方法
EN

Stack Overflow用户
提问于 2018-04-20 17:12:24
回答 1查看 1.6K关注 0票数 1

我想根据先前规则的结果运行规则。如何使用前向链接实现此功能?我不想为每条规则创建一个不同的类对象来实现前向链接。

在本例中,只为这一条规则创建一个InstantDiscount对象以实现前向链接。

代码语言:javascript
复制
public class PreferredCustomerDiscountRule : Rule
{
    public override void Define()
    {
        Customer customer = null;
        IEnumerable<Order> orders = null;
        Double total = Double.NaN;

        When()
            .Match<Customer>(() => customer, c => c.IsPreferred)
            .Query(() => orders, x => x
                .Match<Order>(
                    o => o.Customer == customer,
                    o => o.IsOpen)
                .Collect())
            .Let(() => total, () => orders.Sum(x => x.Amount))
            .Having(() => total > 1000);

        Then()
            .Yield(_ => new InstantDiscount(customer, total * 0.05));
    }
}

public class PrintInstantDiscountRule : Rule
{
    public override void Define()
    {
        InstantDiscount discount = null;

        When()
            .Match(() => discount);

        Then()
            .Do(_ => Console.WriteLine("Customer {0} has instant discount of {1}", 
                discount.Customer.Name, discount.Amount));
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-25 04:31:58

前向链接是一个规则以激活其他规则的方式改变规则引擎的工作记忆的过程。这可以通过在规则引擎中插入新事实(在NRules中使用产率或IContext.Insert ),或者通过更改一些现有事实(使用IContext.Update)来实现。

这里是最初的示例,将折扣附加到客户事实,然后更新该事实以实现前向链接。

代码语言:javascript
复制
public class PreferredCustomerDiscountRule : Rule
{
    public override void Define()
    {
        Customer customer = null;
        IEnumerable<Order> orders = null;
        Double total = Double.NaN;

        When()
            .Match<Customer>(() => customer, c => c.IsPreferred, c => !c.DiscountPercent.HasValue)
            .Query(() => orders, x => x
                .Match<Order>(
                    o => o.Customer == customer,
                    o => o.IsOpen)
                .Collect())
            .Let(() => total, () => orders.Sum(x => x.Amount))
            .Having(() => total > 1000);

        Then()
            .Do(ctx => ApplyDiscount(customer, 0.05))
            .Do(ctx => ctx.Update(customer));
    }

    private static void ApplyDiscount(Customer customer, double discount)
    {
        customer.DiscountPercent = discount;
    }
}

public class DicsountNotificationRule : Rule
{
    public override void Define()
    {
        Customer customer = null;

        When()
            .Match(() => customer, c => c.DiscountPercent.HasValue);

        Then()
            .Do(_ => Console.WriteLine("Customer {0} has instant discount of {1}%", 
                customer.Name, customer.DiscountPercent));
    }
}

当通过更新现有事实进行前向链接时,必须注意不要重新激活更新事实的规则,以避免不必要的递归。在NRules中有几种控制递归的机制:

  • 写入条件时,更新会使规则的条件无效(这是我们在上面的示例中所做的;一旦设置了折扣,规则将不再匹配)
  • 在规则上使用可重复属性来防止再次触发。
  • 使用日程筛选器只在匹配事实发生某些更改时激活规则。

后两个选项在NRules文档中进行了描述。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49946688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档