Codeeffects Linq错误:E106给定的规则集不包含任何类型为System.Xml.Linq.XElement的规则

时间:2017-07-24 10:19:34

标签: rule-engine business-rules codeeffects

当我尝试以下LINQ过滤器

  var productsInfo = from product in productsElement.Descendants("product").Filter(rule)
                           from photo in product.Descendants("photo")
                           from parameter in product.Descendants("parameter")
                           let id = product.Attribute("id")
                           let addr = photo.Attribute("addr")
                           let name = parameter.Attribute("name")
                           select new { ID = id.Value, Addr = addr.Value, Name = name.Value };

我收到以下错误:

The given ruleset does not contain any rules with type
System.Xml.Linq.XElement, System.Xml.Linq, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089 (Error E106)

我的规则:

<?xml version="1.0" encoding="utf-8"?><codeeffects xmlns="http://codeeffects.com/schemas/rule/41" xmlns:ui="http://codeeffects.com/schemas/ui/4"><rule id="09973a56-3d6a-4616-ae1c-40d0d17e95b9" webrule="4.3.6.7" utc="2017-07-24T10:07:08.6346" type="testSlimWebRule.products, testSlimWebRule, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" eval="true"><definition><condition type="equal"><property name="AllProducts.product.id" /><value type="numeric">1</value></condition></definition><format><lines /></format></rule></codeeffects>

XML:

 XDocument productsElement = XDocument.Parse(@"<products>
        <AllProducts>
             <product id='1'>
                 <photo addr='1.jpg'/>
                 <parameter name='name'/>
             </product>
             <product id='2'>
                 <photo addr='2.jpg'/>
                 <parameter name='Kenneth'/>
             </product>
          </AllProducts>
        </products> ");

使用Visual Studio“Insert as XML class”生成的products类:

namespace testSlimWebRule
{
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class products
{

    private productsAllProducts allProductsField;

    /// <remarks/>
    public productsAllProducts AllProducts
    {
        get
        {
            return this.allProductsField;
        }
        set
        {
            this.allProductsField = value;
        }
    }
}

/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class productsAllProducts
{

    private productsAllProductsProduct productField;

    /// <remarks/>
    public productsAllProductsProduct product
    {
        get
        {
            return this.productField;
        }
        set
        {
            this.productField = value;
        }
    }
}

/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class productsAllProductsProduct
{

    private productsAllProductsProductPhoto photoField;

    private productsAllProductsProductParameter parameterField;

    private byte idField;

    /// <remarks/>
    public productsAllProductsProductPhoto photo
    {
        get
        {
            return this.photoField;
        }
        set
        {
            this.photoField = value;
        }
    }

    /// <remarks/>
    public productsAllProductsProductParameter parameter
    {
        get
        {
            return this.parameterField;
        }
        set
        {
            this.parameterField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public byte id
    {
        get
        {
            return this.idField;
        }
        set
        {
            this.idField = value;
        }
    }
}

/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class productsAllProductsProductPhoto
{

    private string addrField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string addr
    {
        get
        {
            return this.addrField;
        }
        set
        {
            this.addrField = value;
        }
    }
}

/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class productsAllProductsProductParameter
{

    private string nameField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string name
    {
        get
        {
            return this.nameField;
        }
        set
        {
            this.nameField = value;
        }
    }
}


}

ASP.net部分:

  <rule:RuleEditor ID="ruleEditor" runat="server"
                Mode="Filter"
                ShowToolBar="false"
                SourceAssembly="testSlimWebRule"
                SourceType="testSlimWebRule.products" />

我尝试了几种设置过滤器的组合,但却找不到解决方案。

我错过了什么?

1 个答案:

答案 0 :(得分:1)

Filter()扩展程序接受一组对象,并分别针对给定规则对其进行评估。规则引擎采用一种集合的元素,并使用它来编译具有该类型参数的lambda。

List<MyClass> list = new List<MyClass>();
list.Filter(rule);

在此示例中,规则的类型为 MyClass ,它将应用于列表中的每个对象,类似于:

Evaluator<MyClass> ev = new Evaluator<MyClass>(rule);
foreach (var item in list)
{
    ev.Evaluate(item);
}

您可以在CodeEffects文档页面上阅读更多内容:Rule-Based Data Filtering Using LINQ to Object Provider

在你的例子中,你犯了一些错误:

  1. 您为XML元素生成类,但不要使用它们。
  2. 自动生成的类错误地映射 AllProduct 字段。它应该是 productsProduct
  3. 的数组
  4. 您将过滤器应用于 XElement 对象的集合,但该规则的类型为 testSlimWebRule.products 。在这种情况下,它应该是 XElement
  5. 以下示例将演示四种可能的选项,第一种是最佳选择。

    主要

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Xml.Linq;
    using System.Xml.Serialization;
    using CodeEffects.Rule.Core;
    
    namespace testSlimWebRule
    {
        class Program
        {
            /* Output:
             * Option A: 1, Bob, 1.jpg
             * Option B: 1, Bob, 1.jpg
             * Option C: 1, Bob, 1.jpg
             * Option D: 2, Kenneth, 2.jpg
             */
            static void Main(string[] args)
            {
                string xml =
                    @"<products>
                        <AllProducts>
                            <product id='1'>
                                <photo addr='1.jpg'/>
                                <parameter name='Bob'/>
                            </product>
                            <product id='2'>
                                <photo addr='2.jpg'/>
                                <parameter name='Kenneth'/>
                            </product>
                        </AllProducts>
                    </products>";
    
                XDocument dom = XDocument.Parse(xml);
    
                products products;
                //You need to load auto-generated classes. I prefer serialization. You may parse XML elements individually.
                using (var xmlReader = dom.CreateReader())
                {
                    var serializer = new XmlSerializer(typeof(products));
                    products = (products)serializer.Deserialize(xmlReader);
                }
    
                string productsProductRule = File.ReadAllText("rule1.xml");
    
                //A: Filter productsProduct[]; result is IEnumerable<productsProduct>.
                //This rule evaluates objects of the productsProduct type.
                var filteredProducts = products.AllProducts.Filter(productsProductRule);
                foreach (var product in filteredProducts)
                    Console.WriteLine("Option A: {0}, {1}, {2}", product.id, product.parameter.name, product.photo.addr);
    
                string xElementRule = File.ReadAllText("rule2.xml");
    
                //B: Filter IEnumerable<XElement>; result is IEnumerable<XElement>.
                //This rule evaluates objects of the XElement type.
                var filteredElements = dom.Descendants("product").Filter(xElementRule);
                foreach (var element in filteredElements)
                    Console.WriteLine("Option B: {0}, {1}, {2}", element.Attribute("id").Value, element.Element("parameter").Attribute("name").Value, element.Element("photo").Attribute("addr").Value);
    
                //C: Filter IEnumerable<XElement>; result is IEnumerable<'a> (anonymous)
                //This rule also evaluates objects of the XElement type.
                var productsInfo = from product in dom.Descendants("product").Filter(xElementRule)
                                   from photo in product.Descendants("photo")
                                   from parameter in product.Descendants("parameter")
                                   let id = product.Attribute("id")
                                   let addr = photo.Attribute("addr")
                                   let name = parameter.Attribute("name")
                                   select new
                                   {
                                       ID = id.Value,
                                       Addr = addr.Value,
                                       Name = name.Value
                                   };
    
                foreach (var info in productsInfo)
                    Console.WriteLine("Option C: {0}, {1}, {2}", info.ID, info.Name, info.Addr);
    
                string anonymousRule = File.ReadAllText("rule3.xml");
    
                //D: Filter IEnumerable<'a>; result is IEnumerable<'a>
                //This rule evaluates objects of the anonymous type 'a with properties ID, Addr, and Name.
                var productsInfo2 = (from product in dom.Descendants("product")
                                     from photo in product.Descendants("photo")
                                     from parameter in product.Descendants("parameter")
                                     let id = product.Attribute("id")
                                     let addr = photo.Attribute("addr")
                                     let name = parameter.Attribute("name")
                                     select new
                                     {
                                         ID = id.Value,
                                         Addr = addr.Value,
                                         Name = name.Value
                                     })
                                    .Filter(anonymousRule);
    
                foreach (var info in productsInfo2)
                    Console.WriteLine("Option D: {0}, {1}, {2}", info.ID, info.Name, info.Addr);
            }
        }
    }
    

    自动生成的课程

    您需要重新粘贴XML示例以生成正确的数组字段。您拥有的是使用只有一条记录的XML示例生成的。但是要过滤,您需要一个集合。

    using System;
    
    namespace testSlimWebRule
    {
    
        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
        public partial class products
        {
    
            private productsProduct[] allProductsField;
    
            /// <remarks/>
            [System.Xml.Serialization.XmlArrayItemAttribute("product", IsNullable = false)]
            public productsProduct[] AllProducts
            {
                get
                {
                    return this.allProductsField;
                }
                set
                {
                    this.allProductsField = value;
                }
            }
        }
    
        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        public partial class productsProduct
        {
    
            private productsProductPhoto photoField;
    
            private productsProductParameter parameterField;
    
            private byte idField;
    
            /// <remarks/>
            public productsProductPhoto photo
            {
                get
                {
                    return this.photoField;
                }
                set
                {
                    this.photoField = value;
                }
            }
    
            /// <remarks/>
            public productsProductParameter parameter
            {
                get
                {
                    return this.parameterField;
                }
                set
                {
                    this.parameterField = value;
                }
            }
    
            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public byte id
            {
                get
                {
                    return this.idField;
                }
                set
                {
                    this.idField = value;
                }
            }
        }
    
        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        public partial class productsProductPhoto
        {
    
            private string addrField;
    
            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string addr
            {
                get
                {
                    return this.addrField;
                }
                set
                {
                    this.addrField = value;
                }
            }
        }
    
        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        public partial class productsProductParameter
        {
    
            private string nameField;
    
            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string name
            {
                get
                {
                    return this.nameField;
                }
                set
                {
                    this.nameField = value;
                }
            }
        }
    }
    

    rule1.xml

    此规则具有正确类型 testSlimWebRule.productsProduct 。它将根据 testSlimWebRule.productsProduct 的自动生成数组中的每个元素进行评估。

    <?xml version="1.0" encoding="utf-8"?>
    <codeeffects xmlns="http://codeeffects.com/schemas/rule/41" xmlns:ui="http://codeeffects.com/schemas/ui/4">
        <rule id="09973a56-3d6a-4616-ae1c-40d0d17e95b9" webrule="4.3.6.7" utc="2017-07-24T10:07:08.6346" type="testSlimWebRule.productsProduct, testSlimWebRule, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" eval="true">
            <definition>
                <condition type="equal">
                    <property name="id" />
                    <value type="numeric">1</value>
                </condition>
            </definition>
        </rule>
    </codeeffects>
    

    rule2.xml

    这条规则就是你的方式。它适用于 System.Xml.Linq.XElement 类型的对象。因此,它只能对该类型的属性和方法进行操作,即您不会获得自定义字段id,addr,name等。

    <?xml version="1.0" encoding="utf-8"?>
    <codeeffects xmlns="http://codeeffects.com/schemas/rule/41" xmlns:ui="http://codeeffects.com/schemas/ui/4">
        <rule id="e38da351-1190-47fb-b99b-d06787c9a459" webrule="4.3.6.7" utc="2017-07-24T10:07:08.6346" type="System.Xml.Linq.XElement, System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" eval="true">
            <definition>
                <condition type="equal">
                    <property name="FirstAttribute.Value" />
                    <value>1</value>
                </condition>
            </definition>
        </rule>
    </codeeffects>
    

    rule3.xml

    此规则没有任何类型。相反,它接收它所评估的任何类型。在示例中,它获取匿名类型&#39; a ,因此它可以对属性ID,名称和地址进行操作。

    <?xml version="1.0" encoding="utf-8"?>
    <codeeffects xmlns="http://codeeffects.com/schemas/rule/41" xmlns:ui="http://codeeffects.com/schemas/ui/4">
        <rule id="7d72463f-5ae2-4617-a2bf-fd605fcb4f54" webrule="4.3.6.7" utc="2017-07-24T10:07:08.6346" type="" eval="true">
            <definition>
                <condition type="startsWith">
                    <property name="Addr" />
                    <value>2</value>
                </condition>
            </definition>
        </rule>
    </codeeffects>