Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在具有多表的Linq查询中使用递归层次树结构并返回一些Json值_C#_Json_Linq_Recursion - Fatal编程技术网

C# 在具有多表的Linq查询中使用递归层次树结构并返回一些Json值

C# 在具有多表的Linq查询中使用递归层次树结构并返回一些Json值,c#,json,linq,recursion,C#,Json,Linq,Recursion,我有一个复杂的层次结构,我使用了这个方法,它返回给我一个包含父节点、子节点和深度的树结构。所以这没关系,但我需要从数据库的ScoreItem表中计算总分。正如我在下面用t-sql编写的这个简单的计算方法一样 Begin Select sp.Name, u.FirstName + ' ' + u.LastName as NameAndSurname, rgc.Name as ScoreCard, si.TotalPoint

我有一个复杂的层次结构,我使用了这个方法,它返回给我一个包含父节点、子节点和深度的树结构。所以这没关系,但我需要从数据库的ScoreItem表中计算总分。正如我在下面用t-sql编写的这个简单的计算方法一样

Begin
    Select 
        sp.Name,
        u.FirstName + ' ' + u.LastName as NameAndSurname, 
        rgc.Name as ScoreCard,
        si.TotalPoint 
    from Score s
        inner join ScoreItem si on si.ScoreId = s.Id
        inner join ProjectResearchGroup prg on si.ProjectResearchGroupId = prg.Id
        inner join RgClone rgc on prg.RgCloneId = rgc.Id
        inner join Salespoint sp on s.SalesPointId = sp.Id
        inner join SalesHierarchySalesPoint shsp on sp.Id = shsp.SalesPointId
        inner join SalesHierarchy sh on shsp.SalesHierarchyId = sh.Id
        inner join [User] u on u.Id = sh.CompanyResponsibleId
    where sh.Id in 
        (Select Id 
        from SalesHierarchy 
        where ParentId in 
            (Select Id 
            from SalesHierarchy 
            where ParentId in 
                (Select Id 
                from SalesHierarchy 
                where ParentId in 
                    (Select Id 
                    from SalesHierarchy 
                    where CompanyId = 2 
                        and ParentId is null))))
        and si.IsValidForSalesPoint = 1 
End 
另外,这是我的后端代码,用于尝试从上述t-sql查询实现linq查询

IEnumerable<FlatData> _SalesHierarchy = db.SalesHierarchy
                                         .Select(sh =>
                                         new FlatData()
                                         {
                                         Id = sh.Id,
                                         ParentId = sh.ParentId ?? 0,
                                         Text = sh.Name
                                         })
                                        .ToList();

IEnumerable<DeepNodeData> nodes = _SalesHierarchy.RecursiveJoin(e => e.Id, e => e.ParentId,
(FlatData sh, int index, int depth, IEnumerable<DeepNodeData> children) =>
  {
    return new DeepNodeData
        {
          Id = sh.Id,
          ParentId = sh.ParentId,
          Text = sh.Text,
          Children = children,
          Depth = depth
        };
如何使用其他linq查询实现层次查询,并返回高于Json格式的结果。如果您对此有任何建议和示例应用程序,请与我分享,

看起来很不错,但我认为您不需要该代码的全部功能来实现您的目标。如果我正确理解您的问题,您需要从根到叶枚举所有节点列表,将每个列表转储到JSON对象中。为此,首先创建以下扩展方法:

public static class RecursiveExtensions
{
    public static IEnumerable<TValue> SelfAndParents<TKey, TValue>(this TValue value, IDictionary<TKey, TValue> dictionary, Func<TValue, TKey> getParentKey)
    {
        HashSet<TValue> returned = new HashSet<TValue>();
        do
        {
            yield return value;
            if (!dictionary.TryGetValue(getParentKey(value), out value))
                yield break;
            if (returned.Contains(value))
                throw new InvalidOperationException("Circular reference");
            returned.Add(value);
        }
        while (true);
    }

    public static IEnumerable<List<TValue>> FlattenTree<TKey, TValue>(this IEnumerable<TValue> nodes, Func<TValue, TKey> getKey, Func<TValue, TKey> getParentKey)
    {
        var list = nodes.ToList();                                                          // Don't iterate through the node list more than once.
        var parentKeys = new HashSet<TKey>(list.Select(getParentKey));                      // Built a set of parent keys.
        var dict = list.ToDictionary(getKey);                                               // Build a dictionary of key to value
        var results = list
            .Where(node => !parentKeys.Contains(getKey(node)))                              // Filter out non-leaf nodes
            .Select(node => node.SelfAndParents(dict, getParentKey).Reverse().ToList());    // For each leaf return a list going from root to leaf.
        return results;
    }
}

这是你想要的吗?在这里,我利用Json.NET将字典序列化为Json对象的事实,动态创建“
levelI
”属性作为字典键。另外,由于您没有定义
“val”
值,所以我没有将其包含在字典中。

val的意思是,总分它来自DbContext上的ScoreItem,它必须显示最后一级的末尾@Ozkan-在
FlatData上没有与
ScoreItem
对应的内容。数据可以添加到那里吗?事实上,我必须加入Score、ScoreItem、Salespoint和SalesHierarchy来准备计算每个Salespoint的积分卡TotalPoint,例如,Alamut Kırtasiye,但谁是Alamut Kırtasiye,谁是其父母??因此,首先我必须得到与阿拉穆特K有关的层次结构。所以“1级”:“Anadolu SatışMerkezi”,“2级”:“Emrullahşelik”,“3级”:“Ahmetşşler”/“4级”:“阿拉穆特K”Val:“45.66”,Val显示了计算的最终全点,例如,请看这里,
public static class RecursiveExtensions
{
    public static IEnumerable<TValue> SelfAndParents<TKey, TValue>(this TValue value, IDictionary<TKey, TValue> dictionary, Func<TValue, TKey> getParentKey)
    {
        HashSet<TValue> returned = new HashSet<TValue>();
        do
        {
            yield return value;
            if (!dictionary.TryGetValue(getParentKey(value), out value))
                yield break;
            if (returned.Contains(value))
                throw new InvalidOperationException("Circular reference");
            returned.Add(value);
        }
        while (true);
    }

    public static IEnumerable<List<TValue>> FlattenTree<TKey, TValue>(this IEnumerable<TValue> nodes, Func<TValue, TKey> getKey, Func<TValue, TKey> getParentKey)
    {
        var list = nodes.ToList();                                                          // Don't iterate through the node list more than once.
        var parentKeys = new HashSet<TKey>(list.Select(getParentKey));                      // Built a set of parent keys.
        var dict = list.ToDictionary(getKey);                                               // Build a dictionary of key to value
        var results = list
            .Where(node => !parentKeys.Contains(getKey(node)))                              // Filter out non-leaf nodes
            .Select(node => node.SelfAndParents(dict, getParentKey).Reverse().ToList());    // For each leaf return a list going from root to leaf.
        return results;
    }
}
public static class TestFlatten
{
    public static IEnumerable<FlatData> GetFlatData()
    {
        // Get sample data for testing purposes.
        var list = new List<FlatData>
        {
            new FlatData { Id = 1, ParentId = 0, Text = "Some Root Node" },
            new FlatData { Id = 2, ParentId = 0, Text = "Anadolu Satış Merkezi" },
            new FlatData { Id = 3, ParentId = 2, Text = "Emrullah Çelik" },
            new FlatData { Id = 4, ParentId = 3, Text = "Ahmet İşler" },
            new FlatData { Id = 5, ParentId = 4, Text = "Elpa Pazarlama Nazmi Appak" },
            new FlatData { Id = 6, ParentId = 4, Text = "Elpa Pazarlama Nazmi Appak Redux" },
            new FlatData { Id = 11, ParentId = 1, Text = "Some Child of Some Root Node" },
        };
        return list;
    }

    public static void Test()
    {
        var nodes = GetFlatData();
        var flatNodes = nodes.FlattenTree(d => d.Id, d => d.ParentId);
        var results = flatNodes.Select(
            list => list
                .Select((d, i) => new KeyValuePair<int, FlatData>(i, d))
                .ToDictionary(pair => string.Format("level{0}", pair.Key + 1), pair => pair.Value.Text))
            .ToList();
        var json = JsonConvert.SerializeObject(new { data = results }, Formatting.Indented);
        Debug.WriteLine(json);
    }
}
{
  "data": [
    {
      "level1": "Anadolu Satış Merkezi",
      "level2": "Emrullah Çelik",
      "level3": "Ahmet İşler",
      "level4": "Elpa Pazarlama Nazmi Appak"
    },
    {
      "level1": "Anadolu Satış Merkezi",
      "level2": "Emrullah Çelik",
      "level3": "Ahmet İşler",
      "level4": "Elpa Pazarlama Nazmi Appak Redux"
    },
    {
      "level1": "Some Root Node",
      "level2": "Some Child of Some Root Node"
    }
  ]
}