c# - 将静态参数转换为哈希表并与 lambda 搜索一起使用

标签 c#

本题为not a duplicate .我正在寻找一种方法,我可以在其中为任意数量的键值参数和相关的 where 子句传入 Hashtable,并且该哈希表可以动态集成到 lambda 搜索中。另一篇文章没有回答这个问题。

我有 3 个重载方法:

public static bool DoesRecordExist(string keyColumn, string keyValue, DataTable dt) {
 if (dt != null && dt.Rows.Count > 0) {
  bool exists = dt.AsEnumerable().Where(r => string.Equals(SafeTrim(r[keyColumn]), keyValue, StringComparison.CurrentCultureIgnoreCase)).Any();
  return exists;
 } else {
  return false;
 }
}

public static bool DoesRecordExist(string keyColumn1, string keyColumn2, string keyValue1, string keyValue2, DataTable dt) {
 if (dt != null && dt.Rows.Count > 0) {
  bool exists = dt.AsEnumerable().Where(r => string.Equals(SafeTrim(r[keyColumn1]), keyValue1, StringComparison.CurrentCultureIgnoreCase) && string.Equals(SafeTrim(r[keyColumn2]), keyValue2, StringComparison.CurrentCultureIgnoreCase)).Any();
  return exists;
 } else {
  return false;
 }
}

public static bool DoesRecordExist(string keyColumn1, string keyColumn2, string keyColumn3, string keyValue1, string keyValue2, string keyValue3, DataTable dt) {
 if (dt != null && dt.Rows.Count > 0) {
  bool exists = dt.AsEnumerable().Where(r => string.Equals(SafeTrim(r[keyColumn1]), keyValue1, StringComparison.CurrentCultureIgnoreCase) && string.Equals(SafeTrim(r[keyColumn2]), keyValue2, StringComparison.CurrentCultureIgnoreCase) && string.Equals(SafeTrim(r[keyColumn3]), keyValue3, StringComparison.CurrentCultureIgnoreCase)).Any();
  return exists;
 } else {
  return false;
 }
}

这些都按预期工作,如您所见,所有 3 个都是相同的,只是参数和相应的 where 子句参数的数量增加了。现在我需要添加另一个包含 5 个键/值对的重载。显然,这变得很愚蠢。

我如何才能将所有这些重载转换为一个函数,在该函数中我只需传入键值对的 Hashtable(或其他一些具有相同或更好意义的集合)?

最佳答案

如果你把它分解成几个部分,这个问题就会简单得多。

首先编写一个检查单个记录是否匹配的函数:

private static bool IsMatch(DataRow row, Dictionary<string,object> filters)
{
    return filters.All( pair => row[SafeTrim(pair.Key)].Equals(pair.Value) );
}

然后将此作为委托(delegate)传递到您的 DoesRecordExist 逻辑中:

public static bool DoesRecordExist(Dictionary<string,object> filters, DataTable dt)
{
    if (dt == null || dt.Rows.Count == 0) return false;
    return dt.AsEnumerable().Any(r => IsMatch(r, filters));
}

以上就是你所需要的。

这是一个使用示例:

public static DataTable CreateTestData()
{
    var data = new []
    {
        new { ID = 1, Name = "John",  DOB = new DateTime(2018,1,1) },
        new { ID = 2, Name = "Paul",  DOB = new DateTime(2018,1,2) },
        new { ID = 3, Name = "Ringo", DOB = new DateTime(2018,1,3) },
        new { ID = 4, Name = "George",DOB = new DateTime(2018,1,4) }
    };
    var table = new DataTable();
    table.Columns.Add("ID", typeof(int));
    table.Columns.Add("Name", typeof(string));
    table.Columns.Add("DOB", typeof(DateTime));
    foreach (var d in data)
    {
        var row = table.NewRow();
        row[0] = d.ID;
        row[1] = d.Name;
        row[2] = d.DOB;
        table.Rows.Add(row);
    }
    return table;
}

public static void Main()
{
    var table = CreateTestData();

    var filter1 = new Dictionary<string,object> { {"ID", 1 } };
    Console.WriteLine("Filter1 exists? {0}", DoesRecordExist(filter1, table));  //Should be true

    var filter2 = new Dictionary<string,object> { { "ID", 1 }, {"Name", "John" } };
    Console.WriteLine("Filter2 exists? {0}", DoesRecordExist(filter2, table));  //Should be true

    var filter3 = new Dictionary<string,object> { { "ID", 1 }, {"Name", "John" }, {"DOB", new DateTime(2018,1,31)} };
    Console.WriteLine("Filter3 exists? {0}", DoesRecordExist(filter3, table));  //Should be false

    var filter4 = new Dictionary<string,object> { { "ID", 1 }, {"Name", "Paul" }, {"DOB", new DateTime(2018,1,2)} };
    Console.WriteLine("Filter4 exists? {0}", DoesRecordExist(filter4, table));  //Should be false
}

输出:

Filter1 exists? True
Filter2 exists? True
Filter3 exists? False
Filter4 exists? False

DotNetFiddle

关于c# - 将静态参数转换为哈希表并与 lambda 搜索一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54047739/

相关文章:

c# - .Net Framework dll 不适用于 .Net Standard 项目

c# - 在 C# Forms 中保存和恢复应用程序设置

c# - axVLCPlugin(VideoLAN) 更快的状态到正常状态

c# - Mono.Cecil - 如何获取自定义属性

c# - 与 PHP 一样,在 C# 中解密使用 AES-256-CBC 加密的数据

c# - 使用匿名类型过滤 ICollectionView 但需要 Predicate<object>?

c# - ASP :Label is not shown when visible is set to true?

c# - 确定可执行文件是否正在运行

c# - 从 SQL Server 调用 REST API

c# - Html Agility Pack,通过站点搜索指定的字符串