【问题标题】:Applying NRules on excel dataset在 excel 数据集上应用 NRules
【发布时间】:2021-12-31 06:46:24
【问题描述】:

我有一个记录数的 Excel。我想在上面应用 Nrule。我想匹配两行并对它们应用规则并检查它是否破坏它。例如:

Id Date Desc
1 12/31/21 Somethings
1 12/31/21 Anything
2 1/1/22 Lorem Epsum

规则:“Somethings”和“Anything”不应出现在同一日期。

因此,这里违反了规则。如何在 NRule 中改正?

【问题讨论】:

  • 您的问题不清楚。 Excel 文件中的记录是代表数据还是规则或两者兼而有之?如果只是数据,请将其加载到域模型中,并将这些对象用作 NRules 的事实(关于如何从 Excel 加载数据的 SO 示例有很多)。如果您尝试在 Excel 中编码规则,则 NRules 不支持。
  • Excel 中的记录代表数据而不是规则
  • 然后,正如我提到的,将数据从 Excel 加载到域模型(如果是 csv 文件,可以使用 CsvHelper 之类的东西)。然后根据该领域模型编写您的规则。

标签: c# rete nrules


【解决方案1】:

如果 Excel 文件是 CSV,您可以使用 CsvHelper 将数据读入域模型。如果它真的是 Excel 文档,那么 SO 上有文章概述了如何从 Excel 加载数据。

使用 CsvHelper 和 NRules,这是加载数据和实现请求规则的一种方法。

using System.Globalization;
using CsvHelper;
using CsvHelper.Configuration;
using NRules;
using NRules.Fluent;
using NRules.Fluent.Dsl;

//Read records from CSV file
using var reader = new StreamReader(@"Data.csv");
var configuration = new CsvConfiguration(CultureInfo.InvariantCulture) { HasHeaderRecord = true };
using var csv = new CsvReader(reader, configuration);
var records = csv.GetRecords<Record>();

//Load rule(s) and compile into NRules session
var repository = new RuleRepository();
repository.Load(x => x.From(typeof(SameDateRule)));
var factory = repository.Compile();
var session = factory.CreateSession();

//Insert records as facts and fire the rules
session.InsertAll(records);
session.Fire();

//Get results from the session
var violations = session.Query<Violation>();
Console.WriteLine($"Found {violations.Count()} violation(s)");

public class Record
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
    [CsvHelper.Configuration.Attributes.Name("Desc")]
    public string Description { get; set; }
}

public class Violation
{
    public Violation(IGrouping<DateTime, Record> records)
    {
        Date = records.Key;
        Records = records.ToArray();
    }

    public DateTime Date { get; }
    public IReadOnlyCollection<Record> Records { get; }
}

public class SameDateRule : Rule
{
    public override void Define()
    {
        IGrouping<DateTime, Record> records = default;

        When()
            .Query(() => records, q => q
                .Match<Record>()
                .GroupBy(x => x.Date)
                .Where(g => g.Any(x => x.Description == "Somethings")
                         && g.Any(x => x.Description == "Anything")));

        Then()
            .Do(ctx => ctx.Insert(new Violation(records)));
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 2017-04-12
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多