将属性传递给C#,EF中的函数

时间:2018-04-06 12:18:31

标签: c# entity-framework lambda expression

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

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

        }

3 个答案:

答案 0 :(得分: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 => i.[Your Attribute](i, o) => 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); 

答案 1 :(得分:1)

这应该有效:

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<SomeClass>类型。 您也可以访问:Get name of property as a string

答案 2 :(得分:0)

您可以指定一个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 );