【问题标题】:C# Linq Column Name as variableC# Linq 列名作为变量
【发布时间】:2013-09-12 10:52:59
【问题描述】:

我有一个表,我想在其中对变量列进行查询。 喜欢:

private void query(string column, string value) {

    using (var db = new myDB()) {

        var s1 = (from c in db.Components
                  where (**column** == **value**)
                  select new {c.id, **column**});
    }
}

假设我想寻找供应商,那么它会是这样的:

var s1 = (from c in db.Components
          where (c.supplier == "abc")
          select new {c.id, c.supplier});

有没有办法将列名作为变量传递?

【问题讨论】:

标签: c# linq entity-framework


【解决方案1】:

我猜这个例子很有用。

 void BindGridTypeSafe()
    {
        NorthwindDataContext northwind = new NorthwindDataContext();

        var query = from p in northwind.Products
                    where p.CategoryID == 3 && p.UnitPrice > 3
                    orderby p.SupplierID
                    select p;

        GridView1.DataSource = query;
        GridView1.DataBind();
    }

    void BindGridDynamic()
    {
        NorthwindDataContext northwind = new NorthwindDataContext();

        var query = northwind.Products
                             .Where("CategoryID = 3 AND UnitPrice > 3")
                             .OrderBy("SupplierID");

        GridView1.DataSource = query;
        GridView1.DataBind();
    }

【讨论】:

  • thx 例如,我试过了,但它给了我一个异常。我发现由于我使用实体框架,因此必须编写 it.COLUMNNAME (it.supplier)。这解决了我使用动态 linq 的问题。谢了!
  • 这是通过添加 Linq.Dynamic 命名空间来使用的。
【解决方案2】:

一个不错的方法是使用Dynamic Linq

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

类似:

var s1 = (from c in db.Components
    where(column + "=" + value)
    select new {c.id, **column**});

【讨论】:

  • 同上例,用户提到使用entityframework,必须写。COLUMNNAME
【解决方案3】:

简短的回答是添加库 System.Linq.Dynamic 作为参考并执行:

string columnName = "Supplier";
var s1 = Suppliers
    .Where(String.Format("{0} == \"abc\"", columnName))
    .Select(new {c.id, c.supplier};

以下是 Dynamic Linq 的完整工作示例,其中 column-name 是一个参数:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;

public class Program
{
    public static void Main()
    {
        var lstContacts = new List<Contact>{
            new Contact{Id = 1, Active = true, Name = "Chris"}, 
            new Contact{Id = 2, Active = true, Name = "Scott"}, 
            new Contact{Id = 3, Active = true, Name = "Mark"}, 
            new Contact{Id = 4, Active = false, Name = "Alan"}};

        string columnName = "Active";
        List<Contact> results = lstContacts.Where(String.Format("{0} == true", columnName)).ToList();

        foreach (var item in results)
        {
            Console.WriteLine(item.Id.ToString() + " - " + item.Name.ToString());
        }
    }
}

public class Contact
{
    public int Id
    {
        get;
        set;
    }

    public bool Active
    {
        get;
        set;
    }

    public string Name
    {
        get;
        set;
    }
}

你可以试试这个.net-fiddle-here

【讨论】:

    【解决方案4】:

    我正在恢复这个旧线程,因为我今天必须使用 ASP.NET Core 2.2 解决这个问题。我使用System.Linq.Dynamic.Core NuGet 包创建了以下扩展方法,如果您需要检查多个给定的字符串值是否包含在多个给定列中,该方法可以很好地工作。

    public static IQueryable<TEntity> WhereContains<TEntity>(
        this IQueryable<TEntity> query,
        string field,
        string value,
        bool throwExceptionIfNoProperty = false,
        bool throwExceptionIfNoType = false)
        where TEntity : class
    {
        PropertyInfo propertyInfo = typeof(TEntity).GetProperty(field);
        if (propertyInfo != null)
        {
            var typeCode = Type.GetTypeCode(propertyInfo.PropertyType);
            switch (typeCode)
            {
                case TypeCode.String:
                    return query.Where(String.Format("{0}.Contains(@0)", field), value);
                case TypeCode.Boolean:
                    var boolValue = (value != null
                        && (value == "1" || value.ToLower() == "true"))
                        ? true
                        : false;
                    return query.Where(String.Format("{0} == @0", field), boolValue);
                case TypeCode.Int16:
                case TypeCode.Int32:
                case TypeCode.Int64:
                case TypeCode.UInt16:
                case TypeCode.UInt32:
                case TypeCode.UInt64:
                    return query.Where(String.Format("{0}.ToString().Contains(@0)", field), value);
    
                // todo: DateTime, float, double, decimals, and other types.
    
                default:
                    if (throwExceptionIfNoType)
                        throw new NotSupportedException(String.Format("Type '{0}' not supported.", typeCode));
                    break;
            }
        }
        else
        {
            if (throwExceptionIfNoProperty)
                throw new NotSupportedException(String.Format("Property '{0}' not found.", propertyInfo.Name));
        }
        return query;
    }
    

    该代码可用于 .NETStandard/.NETCore(使用上述System.Linq.Dynamic.Core 包)以及 ASP.NET 4.x(使用System.Linq.Dynamic 包)。

    有关 WhereContains 扩展方法的更多信息和完整的用例信息,请查看我博客上的 this post

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      • 1970-01-01
      • 2012-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多