【问题标题】:Pass property to a function in C#, EF将属性传递给 C#、EF 中的函数
【发布时间】:2018-04-06 12:18:30
【问题描述】:

我有几种具有通用模式的方法,我想编写一个通用函数,它将列名作为输入并给出相同的结果。

private void Query138()
{
    var products = (from p in _context.Products
                    where p.Manufacturer == null
                    select p);
    foreach (var productItem in products)
    {
        productItem.Manufacturer = string.Empty;
        _context.UpdateProduct(productItem);
    }

}

private void Query139()
{
    var products = (from p in _context.Products
                    where p.ModelNumber == null
                    select p);
    foreach (var productItem in products)
    {
        productItem.ModelNumber = string.Empty;
        _context.UpdateProduct(productItem);
    }

}

我想编写一个通用函数,它将列名作为上述方法的输入。

例子:

 private void Update(Expression<Fun<T,string>> pred = null)
        {
            //use the input column to select the data

            //use the input column to set the new value and update

        }

【问题讨论】:

    标签: c# entity-framework lambda expression


    【解决方案1】:

    您将需要两个表达式来实现这一点。 一个用来获取你的价值,另一个用来设置它。

    private void Update(Expression<Func<T, string>> getter, Expression<Action<T, string>> setter)
        {
            var products = (from p in _context.Products
                            where getter(p) == null
                            select p);
            foreach (var productItem in products)
            {
                setter(productItem, string.Empty);
                _context.UpdateProduct(productItem);
            }
        }
    

    这样你就可以使用i =&gt; i.[Your Attribute](i, o) =&gt; i.[Your Attribute] = o来调用你的函数:

    Update(i => i.[Your Attribute],(i, o) => i.[Your Attribute] = o); 
    

    或者在你的情况下:

    Update(i => i.Manufacturer,(i, o) => i.Manufacturer = o); 
    Update(i => i.ModelNumber,(i, o) => i.ModelNumber = o); 
    

    【讨论】:

      【解决方案2】:

      这应该可行:

      class SomeClass
      {
           public string prop1 { get; set; }
           public string prop2 { get; set; }
      }
      
      ///...
      
      private void Update<T, TReturn>(Expression<Func<T, TReturn>> expression) 
      {
          MemberExpression body = (MemberExpression)expression.Body;
          var propName = body.Member.Name;
          var prop = typeof(SomeClass).GetProperty(propName);
          var products = (from p in contextProds
                          where prop.GetValue(p) == null
                          select p);
          ///...
      }
      

      用法:

      Update((SomeClass s) => s.prop1);
      Update((SomeClass s) => s.prop2);
      

      contextProds 类似于 List&lt;SomeClass&gt; 类型。 您也可以访问:Get name of property as a string

      【讨论】:

      • 这可能适用于 LINQ to Entities。我在 LINQ to SQL 中遇到异常:方法 'System.Object GetValue(System.Object)' 没有支持的 SQL 转换。
      • 你一直在看这个吗,@sudhAnsu63? stackoverflow.com/questions/22104050/…
      【解决方案3】:

      您可以指定一个 getter 并使用它来生成一个 setter。这可以通过以下方式实现:

      private void Update(Expression<Func<Product, string>> getExpr)
      {
          var value = Expression.Parameter(typeof(string), "value");
          var setExpr = Expression.Lambda<Action<Product, string>>(
              Expression.Assign(getExpr.Body, value), getExpr.Parameters[0], value);
      
          Func<Product, string> getter = getExpr.Compile();
          Action<Product, string> setter = setExpr.Compile();
      
          var products = (from p in _context.Products
                          where getter(p) == null
                          select p);
          foreach (var productItem in products)
          {
              setter(productItem, string.Empty);
              _context.UpdateProduct(productItem);
          }
      }
      

      然后调用如下:

      Update( x => x.ModelNumber );
      

      【讨论】:

      • 而不是 getter Func 你最好构建 Expression&lt;Product, bool&gt; 并直接在 _context.Products.Where 中使用它。您当前建议的方式将导致检索整个表并执行过滤客户端。
      • LINQ to SQL 异常:方法“System.Object DynamicInvoke(System.Object[])”不支持对 SQL 的转换。可能在 LINQ to Entities 上工作。
      猜你喜欢
      • 1970-01-01
      • 2013-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-26
      • 2014-03-24
      • 1970-01-01
      相关资源
      最近更新 更多