【问题标题】:C# Pass lambda expression field into method and use field in linq queryC# 将 lambda 表达式字段传递给方法并在 linq 查询中使用字段
【发布时间】:2016-09-01 23:49:09
【问题描述】:

如何将字段(通过 lambda 表达式)传递给方法,然后将该字段用作 linq 查询的一部分?

我想调用类似的方法

IDictionary<string, string> stuff = foo(items, otherItems, otherItems => otherItems.FieldToUse)

我不确定如何编写该方法,但我想像下面的代码一样使用它。我知道我可以使用泛型并将字段名称(通过字符串)传递给方法,但即便如此我也不知道如何在 linq 查询中使用它,如下所示。另外,我喜欢使用 lambda,因为我可以随时重命名字段。

private IDictionary<string, string> foo<TModel>(IEnumerable<string> items, IEnumerable<TModel> otherItems, object FieldToUse)
    {
        //this will return a list of key value pairs of rowIDs and equipment
        IDictionary<string, string> x = (from o in otherItems
                                         join i in items on o.FieldToUse.ToString() equals i //joining on the equipment assetcode
                                         select new { rowID = o.RowID, item = i }).ToDictionary(k => k.rowID.ToString(), v => v.item);
        return x;
    }

澄清:FieldToUse 是 TModel 的一个属性或字段

【问题讨论】:

  • 问题不是很清楚。 FieldsToUse 是 otherItems 中的一种类型?在传递 otherItems 时,不需要传递字段。
  • 我并不总是想使用相同的属性调用方法,即使我对 TModel 使用相同的类型。有时我想使用一个属性,有时又想使用另一个属性
  • 我认为您想使用选择器。一个示例是 LINQ 的 OrderBy 方法,您可以在其中调用 .OrderBy(obj => obj.Property);这就是你要找的东西吗?
  • 你需要这个来对抗 LINQ to Entities/SQL 吗?还是对普通物体起作用就足够了?

标签: c# linq lambda parameters


【解决方案1】:

使用Func Delegate

将方法foo中的最后一个参数更改为

Func<TModel, String> FieldToUse

并在 LINQ 查询中调用函数

FieldToUse(o)

这是整个方法 foo

private IDictionary<string, string> foo<TModel>(IEnumerable<string> items,
  IEnumerable<TModel> otherItems,
  Func<TModel, String> FieldToUse)
{
  //this will return a list of key value pairs of rowIDs and equipment
  IDictionary<string, string> x = (from o in otherItems
                                   join i in items on FieldToUse(o) equals i //joining on the equipment assetcode
                                   select new { rowID = o.RowID, item = i })
                                   .ToDictionary(k => k.rowID.ToString(), v => v.item);
  return x;
}

你可以这样使用它

public void DoStuff()
{
  string[] items = { "abc", "def", "ghi" };
  List<Model> otherItems = new List<Model> { 
        new Model() { Field1 = "abc", Field2 = "xyz" }, 
        new Model() { Field1 = "abc", Field2 = "xyz" } };

  var result = foo<Model>(items, otherItems, a => a.Field2);
}

class Model 
{
  public string Field1 { get; set; }
  public string Field2 { get; set; }
}

不过,您还会遇到另一个问题。通用 TModel 没有 RowID。或许为 TModel 提供一个generic where constraint

代码就变成了

 private IDictionary<string, string> foo<TModel>(IEnumerable<string> items,
  IEnumerable<TModel> otherItems,
  Func<TModel, String> FieldToUse) where TModel : BaseModel
{
  //this will return a list of key value pairs of rowIDs and equipment
  IDictionary<string, string> x = (from o in otherItems
                                   join i in items on FieldToUse(o) equals i //joining on the equipment assetcode
                                   select new { rowID = o.RowID, item = i })
                                   .ToDictionary(k => k.rowID.ToString(), v => v.item);
  return x;
}

class BaseModel
{
  public int RowID { get; set; }
}
class Model : BaseModel
{
  public string Field1 { get; set; }
  public string Field2 { get; set; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多