首页 > 解决方案 > 如何将 2 个 db 调用合并为一个

问题描述

如何将以下 2 个 db 调用合并为一个。有可能吗?

IEnumerable<int> NewIds= Table1.NewValue.Split(',')
  .Where(x => int.TryParse(x, out int num))
  .Select(int.Parse)
  .ToList();

if (NewIds!= null && NewIds.Count() > 0)
{
   NewValue = string.Join(",", _context.table1.Where(x => NewIds.Contains(x.Id))
                                              .Select(x => TempTextHelper.L(x.Name)));
}

IEnumerable<int> oldIds = Table1.OldValue.Split(',')
  .Where(x => int.TryParse(x, out int num))
  .Select(int.Parse)
  .ToList();

if (oldIds != null && oldIds.Count() > 0)
{
    OldValue = string.Join(",", _context.table1.Where(x => oldIds.Contains(x.Id))
                                        .Select(x => TempTextHelper.L(x.Name)));
}

谢谢并恭祝安康,

标签: c#entity-frameworklinq

解决方案


为了避免逻辑重复,创建一个从字符串值获取 id 的方法。您还可以避免将每个字符串解析两次,并将解析结果聚合到哈希集。很好的方法是扩展方法:

public static class Extensions
{
    public static HashSet<int> GetIds(this string value) =>
          value.Split(',').Aggregate(new HashSet<int>(),
              (acc, s) => { if (Int32.TryParse(s, out int x)) acc.Add(x); return acc; });
}

另外我会在同一个类中添加第二个辅助方法(见后面的用法):

public static string CreateValue(this IEnumerable<KeyValuePair<int, string>> items) =>
  String.Join(',', items.Select(kvp => TempTextHelper.L(kvp.Value)));

现在获取所有 id 并查询所有内容,但也将 Id 包含到结果中:

var newIds = Table1.NewValue.GetIds();
var oldIds = Table1.OldValue.GetIds();
var ids = newIds.Union(oldIds).ToList(); // combine two sets of ids
if (ids.Any())
{
    // Single DB call
    var allResults = 
      _context.table1.Where(x => ids.Contains(x.Id)).ToDictionary(x => x.Id, x => x.Name);

    NewValue = allResults.Where(kvp => newIds.Contains(kvp.Key)).CreateValue();
    OldValue = allResults.Where(kvp => oldIds.Contains(kvp.Key)).CreateValue();
}

推荐阅读