Как получить замененную переменную с именем поля в LINQ?

Вопрос:
string companyName="ABC";
var query = from q in context.Company where q.CompanyName == companyName select q;

Есть ли способ заменить часть q.CompanyName запроса на q.CompanyName переменную, чтобы поле, используемое для фильтрации, было параметрическим?

Я пытался

string str1 = "companySize";
string str2 = "q." + str1;
string companySize = "Mid";
var query = from q in context.Company where str2 == companySize select q;

Не работает. Пробовал позволить пользователю выбрать столбцы для запроса.

Лучший ответ:

Подробнее об этом можно узнать в следующем разделе: Динамический запрос с Linq

вы можете использовать один из этих

  1. Использование библиотеки Dynamic LINQ

    Пример для блога ниже

    string strWhere = string.Empty;
    string strOrderBy = string.Empty;
    
    if (!string.IsNullOrEmpty(txtAddress.Text))
        strWhere = "Address.StartsWith(\"" + txtAddress.Text + "\")"; 
    if (!string.IsNullOrEmpty(txtEmpId.Text))
    {
        if(!string.IsNullOrEmpty(strWhere ))
            strWhere = " And ";
        strWhere = "Id = " + txtEmpId.Text;
    }
    if (!string.IsNullOrEmpty(txtDesc.Text))
    {
        if (!string.IsNullOrEmpty(strWhere))
            strWhere = " And ";
        strWhere = "Desc.StartsWith(\"" + txtDesc.Text + "\")";
    }
    if (!string.IsNullOrEmpty(txtName.Text))
    {
        if (!string.IsNullOrEmpty(strWhere))
            strWhere = " And ";
        strWhere = "Name.StartsWith(\"" + txtName.Text + "\")";
    }
    
    EmployeeDataContext edb = new EmployeeDataContext();
    var emp = edb.Employees.Where(strWhere);
    
  2. Predicate Builder

Пример

    var predicate = PredicateBuilder.True<employee>();

    if(!string.IsNullOrEmpty(txtAddress.Text))
        predicate = predicate.And(e1 => e1.Address.Contains(txtAddress.Text));
    if (!string.IsNullOrEmpty(txtEmpId.Text))
        predicate = predicate.And(e1 => e1.Id == Convert.ToInt32(txtEmpId.Text));
    if (!string.IsNullOrEmpty(txtDesc.Text))
        predicate = predicate.And(e1 => e1.Desc.Contains(txtDesc.Text));
    if (!string.IsNullOrEmpty(txtName.Text))
        predicate = predicate.And(e1 => e1.Name.Contains(txtName.Text));

    EmployeeDataContext edb= new EmployeeDataContext();
    var emp = edb.Employees.Where(predicate);

Ответ №1

Я думаю, что лучший способ сделать это – со встроенными библиотеками (и PropertyDescriptor).

using System.ComponentModel;

void Main()
{
Test test = new Test();
test.CompanyName = "ABC";

object z = TypeDescriptor.GetProperties(test).OfType<PropertyDescriptor>()
.Where(x => x.Name == "CompanyName").Select(x => x.GetValue(test)).FirstOrDefault();

Console.WriteLine(z.ToString());
}

public class Test
{
public string CompanyName { get; set; }
}

Ответ №2

Если вы не хотите использовать библиотеки, такие как dynamicLINQ, вы можете просто создать Дерево выражений самостоятельно:

string str1 = "companySize";
string str2 = "q." + str1;
string companySize = "Mid";

var param = Expression.Parameter(typeof(string));
var exp = Expression.Lambda<Func<Company, bool>>(
Expression.Equal(
Expression.Property(param, str1),
Expression.Constant(companySize)),
param);

var query = context.Company.Where(exp);

Оцените статью
TechArks.Ru
Добавить комментарий