0

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

ID 日期 描述
1 21 年 12 月 31 日 东西
1 21 年 12 月 31 日 任何事物
2 22 年 1 月 1 日 Lorem Epsum

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

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

4

1 回答 1

0

如果 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)));
    }
}
于 2022-01-11T05:06:34.167 回答