2017-01-19 3 views
0

Я уверен, что этот вопрос задан раньше, но я не смог его найти. Я хочу отфильтровать список имен таблиц в зависимости от нескольких критериев, которые в конечном итоге будут определены пользователем. Следующий мой текущий код.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 в операции фильтрации. Однако эти значения могут быть нулевыми, и в этом случае они не будут использоваться в фильтре. Я считаю, что должен быть более простой способ сделать это, чем писать отдельный оператор linq для каждого условия?

Заранее спасибо.

ответ

1

Вы можете использовать? который поможет вам в этом:

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; 
} 
+0

Это будет работать хорошо для меня. Я думаю, что это решение более читаемо, чем использование комбинации и/или операторов. Спасибо. – user1165224

+0

@ user1165224 Рад, что это помогло. –

1

Уверенный, вы можете это сделать. Просто примените нулевую проверку в предложении или перед фактическим условием.

Пример:

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; 
} 
0

Вы можете использовать метод 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; 
} 
3

Вы можете использовать отдельные 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(); 
+0

Это была моя первая попытка, но она не будет компилироваться. nameQuery становится элементом типа LIst <> и не может быть установлен во втором фильтре, потому что результат имеет тип IEnumerable <>. Легко исправить, но я подумал, что может быть более простое решение. – user1165224

+0

Это, конечно, правильный ответ. +1 @ user1165224 Нет пути 'nameQuery' стать' List ', если вы не вызываете' ToList() '. –

+0

Я набрал вышеуказанное и не получил ошибку (исправление скобок). Я, должно быть, сделал что-то смешное в первый раз. Если бы у меня были какие-то критерии, я бы предпочел разбить их, чтобы сделать его более читаемым, чем одно длинное заявление linq. – user1165224

Смежные вопросы