Linq 按可能存在也可能不存在的多个值进行筛选



我确定这个问题以前有人问过,但我找不到它。我想根据最终将由用户确定的几个条件过滤表名称列表。以下是我当前的代码。

private List<TableMetaData> tableMetaData = new List<TableMetaData>();
public class TableMetaData
{
    public string TableName;
    public string ReferenceTableName;
    public bool IsAuditTable;
    public bool IsSyncTable;
    public bool IsView;
}
public List<string> GetTableNames(TableMetaData filterData)
{
    List<string> filteredNames = tableMetaData
        .Where(table => (table.IsAuditTable == filterData.IsAuditTable)
            && (table.IsSyncTable == filterData.IsSyncTable)
            && (table.IsView == filterData.IsView))
        .Select(table => table.TableName).ToList();
    return filteredNames;
}

我仍然需要在过滤操作中包含 TableMetaData.TableName 和 TableMetaData.ReferenceTableName。但是,这些值可能为 null,在这种情况下,它们不会在筛选器中使用。我认为一定有一种比为每个条件编写单独的 linq 语句更简单的方法?

提前谢谢你。

您可以使用

单独的Where调用,这使它具有更高的可读性(在我看来)

var nameQuery = tableMetaData
    .Where(table => (table.IsAuditTable == filterData.IsAuditTable)
        && (table.IsSyncTable == filterData.IsSyncTable)
        && (table.IsView == filterData.IsView));
if (filterData.TableName != null)
     nameQuery = nameQuery.Where(table => table.TableName == filterData.TableName);
if (filterData.ReferenceTableName != null)
     nameQuery = nameQuery.Where(table => table.ReferenceTableName == filterData.ReferenceTableName);
// more criteria ..
return  nameQuery.Select(table => table.TableName).ToList();
您可以使用

? 运算符来帮助您解决此问题,如下所示:

public List<string> GetTableNames(TableMetaData filterData)
{
    List<string> filteredNames = tableMetaData
        .Where(table => (table.IsAuditTable == filterData.IsAuditTable)
            && (table.IsSyncTable == filterData.IsSyncTable)
            && (table.IsView == filterData.IsView)
            && (filterData.ReferenceTableName == null ? true : table.ReferenceTableName == filterData.ReferenceTableName)
            && (filterData.TableName == null ? true : table.TableName == filterData.TableName))
        .Select(table => table.TableName).ToList();
    return filteredNames;
}

当然你可以这样做。只需在实际条件之前在 or 子句中应用 null 检查即可。

例:

public List<string> GetTableNames(TableMetaData filterData)
{
    List<string> filteredNames = tableMetaData
        .Where(table => (table.IsAuditTable == filterData.IsAuditTable)
            && (table.IsSyncTable == filterData.IsSyncTable)
            && (table.IsView == filterData.IsView)
            && ((table.TableName == null) || (table.TableName == "Something"))
            && ((table.ReferenceTableName == null) || (table.ReferenceTableName == "Something")))
        .Select(table => table.TableName).ToList();
    return filteredNames;
}
可以使用

string.IsNullOrEmpty 方法确定这些字符串中的任何一个是null还是空 (")。像这样:

public List<string> GetTableNames(TableMetaData filterData)
{
    List<string> filteredNames = tableMetaData
        .Where(table => (table.IsAuditTable == filterData.IsAuditTable)
            && (table.IsSyncTable == filterData.IsSyncTable)
            && (table.IsView == filterData.IsView)
        && (string.IsNullOrEmpty(filterData.ReferenceTableName) || table.TableName == filterData.TableName)
        && (string.IsNullOrEmpty(filterData.ReferenceTableName) || table.ReferenceTableName == filterData.ReferenceTableName))
        .Select(table => table.TableName).ToList();
    return filteredNames;
}

最新更新