首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NRules:为复杂类型构建规则

NRules:为复杂类型构建规则
EN

Stack Overflow用户
提问于 2020-01-03 09:03:16
回答 1查看 540关注 0票数 0

给定以下域模型

代码语言:javascript
复制
public class Person
{
  public string Name { get; set; }
  public int Age { get; set; }
  public List<Car> Cars { get; set; }
}
public class Car
{
    public int Year { get; set; }
    public string Make { get; set; }
}

有没有可能写一条规则,对30岁以下的人拥有的所有2016年以上的汽车执行操作?我这样做时,只将Person对象作为事实插入。

代码语言:javascript
复制
Person p1 = new Person("Jim", 31);
p1.Cars = GetCars(4);
Person p2 = new Person("Bob", 29);
p2.Cars = GetCars(4);

session.Insert(p1);
session.Insert(p2);

我试过这样的东西。我猜如果我在汽车中添加一个对拥有它的人的引用,我可以让它工作,但我的实际用例将使这一点变得困难。我希望我只是错过了什么。

代码语言:javascript
复制
public class CarTest : Rule
{
  public override void Define()
  {
    Person person = null;           
    IEnumerable<Car> cars = null;

    When()
      .Match<Person>(() => person, p => p.Age < 30)
      .Query(() => cars, x => x
         .Match<Car>(c => c == person.Cars.Find(f=> f.Make == c.Make && f.Year == c.Year), c => c.Year > 2016)
         .Collect()
         .Where(p => p.Any()));
    Then()
      .Do(ctx => DoSomethingWithNewCarsThatBelongToYoungPeople(cars));

  }

  private static void DoSomethingWithNewCarsThatBelongToYoungPeople(IEnumerable<Car> cars)
  {
     foreach (var car in cars)
     {
        //Do Something
     }
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-13 11:50:05

通过joins处理复杂匹配上的聚合的最好方法是将其分成两个规则,并使用正向链接。

第一条规则将给定的年轻人与他们被认为是新车的汽车进行匹配。然后,它会产生一个新的事实来包装结果。

代码语言:javascript
复制
public class YoungPersonWithNewCarRule : Rule
{
    public override void Define()
    {
        Person person = null;
        IEnumerable<Car> cars = null;

        When()
            .Match(() => person, p => p.Age < 30)
            .Let(() => cars, () => person.Cars.Where(c => c.Year > 2016))
            .Having(() => cars.Any());
        Then()
            .Yield(ctx => new YoungPersonWithNewCar(person, cars));
    }
}

public class YoungPersonWithNewCar
{
    private readonly Car[] _cars;

    public Person Person { get; }
    public IEnumerable<Car> Cars => _cars;

    public YoungPersonWithNewCar(Person person, IEnumerable<Car> cars)
    {
        _cars = cars.ToArray();
        Person = person;
    }
}

第二条规则匹配第一条规则产生的事实,并将它们聚合到一个集合中。

代码语言:javascript
复制
public class YoungPeopleWithNewCarsHandlingRule : Rule
{
    public override void Define()
    {
        IEnumerable<YoungPersonWithNewCar> youngPeopleWithNewCars = null;

        When()
            .Query(() => youngPeopleWithNewCars, q => q
                .Match<YoungPersonWithNewCar>()
                .Collect()
                .Where(c => c.Any()));
        Then()
            .Do(ctx => DoSomethingWithNewCarsThatBelongToYoungPeople(youngPeopleWithNewCars));
    }

    private void DoSomethingWithNewCarsThatBelongToYoungPeople(IEnumerable<YoungPersonWithNewCar> youngPeopleWithNewCars)
    {
        //
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59571983

复制
相关文章

相似问题

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