实体框架 where 子句从特定列过滤

arb*_*ity 2 c# linq entity-framework dynamic where-clause

我在使用 Entity Framework 6 时遇到问题,但不知道如何解决。我想使用 EntityFramework 从表中读取数据。目标是使用 where 子句读取该数据,该子句从特定列中过滤数据。我要搜索的列在方法参数中指定。

一个例子:我有一张人员表

姓名 地址 电子邮件
康纳 布莱恩 纽约 abc@abc.com
施瓦辛格 阿诺德 洛杉矶 abc@abc.com

通常我会选择这样的数据:

public List<Person> getData(string searchTerm)
{
    using (var db = new myDB())
    {
      return db.Person.Where(x=> x.Name == searchTerm).ToList();
    } 
}

Run Code Online (Sandbox Code Playgroud)

但我也希望能够灵活地处理我想要过滤的列。像这样的东西:

public getData(string columnToSearch, string searchTerm)
{
     using (var db = new myDB())
    {
      return db.Person.Where(columnToSearch == searchTerm).ToList();
    } 
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

我不想使用纯 SQL 并且无法编辑数据库。

感谢您的帮助。

Cai*_*ard 5

鉴于你只有 4 列,我真的认为我会:

public List<Person> GetData(string columnToSearch, string searchTerm)
{
    using var db = new myDB();
  
    if(columnToSearch == "Name")
      return db.Person.Where(p => p.Name == searchTerm).ToList();
    else if(columnToSearch == "FirstName")
      return db.Person.Where(p => p.FirstName == searchTerm).ToList();
    else if(columnToSearch == "Adress")
      return db.Person.Where(p => p.Adress == searchTerm).ToList();
    else if(columnToSearch == "Email")
      return db.Person.Where(p => p.Email == searchTerm).ToList();
    else
       throw ..
}
Run Code Online (Sandbox Code Playgroud)

..或一些类似的选择结构..

public List<Person> GetData(string columnToSearch, string searchTerm)
{
    using var db = new myDB();
  
    return (columnToSearch switch {
        "Name" => db.Person.Where(p => p.Name == searchTerm),
        "FirstName" => db.Person.Where(p => p.FirstName == searchTerm)
        "Adress" => db.Person.Where(p => p.Adress == searchTerm)
        "Email" => db.Person.Where(p => p.Email == searchTerm)
        _ => throw new ArgumentException(nameof(columnToSearch) + " should be one of: Name, FirstName, Adress, Email")
    }).ToList();
}
Run Code Online (Sandbox Code Playgroud)

..甚至可以切换进行挑选的委托:

public List<Person> GetData(string columnToSearch, string searchTerm)
{
    Func<Person, bool> what = columnToSearch switch {
        "Name" => p => p.Name == searchTerm,
        "FirstName" => p => p.FirstName == searchTerm
        "Adress" => p => p.Adress == searchTerm
        "Email" => p => p.Email == searchTerm
        _ => throw new ArgumentException(nameof(columnToSearch) + " should be one of: Name, FirstName, Adress, Email")
    };

    using var db = new myDB();
    return db..Person.Where(what).ToList();
}
Run Code Online (Sandbox Code Playgroud)

即使此表中有 20 列,使用多行编辑器编写如下重复代码也相当容易:

在此输入图像描述

这是一个名为 Sublime 的编辑器,但 VS 也可以这样做,要么使用ctrl+ alt+ 单击来放置多个光标,要么选择一些常见的东西并按shift+ alt+ .。如果你使用 VS,你需要安装“Multiple Caret Booster”扩展,否则粘贴会变得疯狂;在大多数执行多个插入符号的编辑器中,如果您有例如 20 个插入符号,并且从剪贴板粘贴 20 行(例如 20 个列名称),则每个插入符号会获得一个剪辑行。在 VS 中,通常你会得到每个插入符的所有 20 行(粘贴了 400 行),这使得将所有 20 列都放在剪贴板上并将它们粘贴到代码流中(就像上面的动画一样)非常困难