C# 如何将其作为单个LINQ查询编写?

C# 如何将其作为单个LINQ查询编写?,c#,.net,linq,.net-3.5,C#,.net,Linq,.net 3.5,使用以下逻辑,单个LINQ查询的正确语法是什么 如果分支是服务,我想要它的父级,否则我想要分支。 你能评论我的尝试并告诉我如何改进它吗 int branchId = 21; var t = ctx.BranchInfos.Single(p => p.BranchID == branchId ); if (t.Type == BranchType.Service.ToString()) { t = ctx.BranchInfos.Single(p => p.BranchID =

使用以下逻辑,单个LINQ查询的正确语法是什么

如果分支是服务,我想要它的父级,否则我想要分支。

你能评论我的尝试并告诉我如何改进它吗

int branchId = 21;
var t = ctx.BranchInfos.Single(p => p.BranchID == branchId );
if (t.Type == BranchType.Service.ToString())
{
    t = ctx.BranchInfos.Single(p => p.BranchID == t.Parent);
}

我很肯定你可以用一个LINQ语句来完成,但我同样肯定你不应该这样做。它不会提高可读性,也很难提高性能

var t = ctx.BranchInfos.Single(x =>
  (
    x.BranchID == branchID &&
    x.Type != BranchType.Service.ToSting()
  )
  ||
  (
    ctx.BranchInfos.Any(
      y.BranchID == branchID) &&
      y.Type == BranchType.Service.ToSting()) &&
    x.BranchID == ctx.BranchInfos.Single(
      y.BranchID == branchID) &&
      y.Type == BranchType.Service.ToSting()).ParentID
  )
);
很好,不是吗我还是建议不要用它。第一种情况很简单-如果项目具有正确的ID并且不是服务类型,则我们有一个匹配项


第二种情况更为棘手。我们必须检查该项是否具有来自具有所提供ID的项的ParentID属性的ID,但仅当具有所提供ID的项是服务类型时。由于我们在检查此项时不知道是否存在具有提供的ID和类型服务的项,因此我们必须首先使用
Any()
检查是否存在此类项,并依赖于
的条件求值,我确信您可以使用单个LINQ语句来完成此操作,但我同样确信你不应该这样做。它不会提高可读性,也很难提高性能

var t = ctx.BranchInfos.Single(x =>
  (
    x.BranchID == branchID &&
    x.Type != BranchType.Service.ToSting()
  )
  ||
  (
    ctx.BranchInfos.Any(
      y.BranchID == branchID) &&
      y.Type == BranchType.Service.ToSting()) &&
    x.BranchID == ctx.BranchInfos.Single(
      y.BranchID == branchID) &&
      y.Type == BranchType.Service.ToSting()).ParentID
  )
);
var t = ctx.BranchInfos.Single(
  p => (p.BranchID == branchId && p.Type != BranchType.Service.ToString) ||
       (p.BranchID == GetBranchParentId(branchId) && p.Type == BranchType.Service.ToString));
很好,不是吗我还是建议不要用它。第一种情况很简单-如果项目具有正确的ID并且不是服务类型,则我们有一个匹配项

第二种情况更为棘手。我们必须检查该项是否具有来自具有所提供ID的项的ParentID属性的ID,但仅当具有所提供ID的项是服务类型时。由于我们在检查此项时不知道是否存在具有提供的ID和类型服务的项,因此必须首先使用
Any()
检查是否存在此类项,并依赖
的条件求值

var t = ctx.BranchInfos.Single(
  p => (p.BranchID == branchId && p.Type != BranchType.Service.ToString) ||
       (p.BranchID == GetBranchParentId(branchId) && p.Type == BranchType.Service.ToString));
其中GetBranchParentId是一个函数,它返回id作为参数传递的分支的BranchHid

但是,我喜欢您的原始代码,所以我不会使用单个查询来获取数据

其中GetBranchParentId是一个函数,它返回id作为参数传递的分支的BranchHid


但是,我喜欢您的原始代码,因此我不会使用单个查询来获取数据。

我认为您可以这样做:

var t=ctx.BranchInfos.FirstOrDefault(p=>p.branchhid==branchhid | | p.branchhid==t.Parent)


迈克

我想你可以这样做:

var t=ctx.BranchInfos.FirstOrDefault(p=>p.branchhid==branchhid | | p.branchhid==t.Parent)


迈克

除非我弄乱了逻辑,否则这可能会满足你的需要

编辑:不同的方法

var t = ctx.BranchInfos.Where(p.BranchID == branchId).First(p => p.Type == BranchType.Service.ToString() ? p.Parent : p);

除非我弄乱了逻辑,否则这可能会满足你的需要

编辑:不同的方法

var t = ctx.BranchInfos.Where(p.BranchID == branchId).First(p => p.Type == BranchType.Service.ToString() ? p.Parent : p);

这可能行得通,但有点尴尬

var t = ctx.BranchInfos.Where(p => p.BranchID == branchId)
    .Select(p => 
      p.Type != BranchType.Service.ToString() 
      ? p 
      : ctx.BranchInfos.Single(t => p.Parent == t.BranchId)).FirstOrDefault();

这可能行得通,但有点尴尬

var t = ctx.BranchInfos.Where(p => p.BranchID == branchId)
    .Select(p => 
      p.Type != BranchType.Service.ToString() 
      ? p 
      : ctx.BranchInfos.Single(t => p.Parent == t.BranchId)).FirstOrDefault();

我建议,如果这只需要在一个地方,那么你现在所拥有的是相当清楚的,应该保留

如果您经常这样做,请执行以下操作:

public static BranchInfo BranchOrServiceParent(
    this IEnumerable<BranchInfo> input)
{ 
    var t = BranchInfos.Single(p => p.BranchID == branchId);
    if (t.Type == BranchType.Service.ToString())    
        t = input.BranchInfos.Single(p => p.BranchID == t.Parent);
    return t;
}
如果您随后需要参数化/更改,您可以以清晰的方式进行


如果您随后发现两次可能的数据库访问是一个性能问题,那么您可以尝试一个复杂的Linq查询,或者接受这可能实际上需要由存储过程来完成。

我建议,如果只在一个地方需要,那么您现在所拥有的是相当清楚的,应该保留下来

如果您经常这样做,请执行以下操作:

public static BranchInfo BranchOrServiceParent(
    this IEnumerable<BranchInfo> input)
{ 
    var t = BranchInfos.Single(p => p.BranchID == branchId);
    if (t.Type == BranchType.Service.ToString())    
        t = input.BranchInfos.Single(p => p.BranchID == t.Parent);
    return t;
}
如果您随后需要参数化/更改,您可以以清晰的方式进行


如果您随后发现两次可能的数据库访问是一个性能问题,那么您可以尝试一个复杂的Linq查询,或者接受这可能实际上需要由存储过程来完成。

我相信以下内容相当于您的代码示例。我添加了一些模拟代码,将其转换为一个自包含的示例

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Context ctx = new Context();
            ctx.BranchInfos.Add(new BranchInfo() { Type = "NonService", BranchID = 20, Parent = 0 });
            ctx.BranchInfos.Add(new BranchInfo() { Type = "Service", BranchID = 21, Parent = 20 });
            ctx.BranchInfos.Add(new BranchInfo() { Type = "NonService", BranchID = 30, Parent = 20 });

            int branchId = 21;

            var t = (from a in ctx.BranchInfos
                     where a.BranchID == branchId
                     select a.Type != BranchType.Service.ToString() ? a :
                     (from b in ctx.BranchInfos
                      where b.BranchID == a.Parent
                      select b).Single()).Single();

            Console.WriteLine(t.BranchID); // Prints 20
        }

        class Context
        {
            public List<BranchInfo> BranchInfos = new List<BranchInfo>();
        }

        class BranchInfo
        {
            public string Type;
            public int BranchID;
            public int Parent;
        }

        enum BranchType
        {
            Service = 0
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
Context ctx=新上下文();
添加(new BranchInfo(){Type=“NonService”,branchhid=20,Parent=0});
添加(new BranchInfo(){Type=“Service”,BranchID=21,Parent=20});
添加(new BranchInfo(){Type=“NonService”,branchhid=30,Parent=20});
int=21;
变量t=(来自ctx.BranchInfos中的a
其中a.BranchID==BranchID
选择a.Type!=BranchType.Service.ToString()?a:
(来自ctx.BranchInfos中的b)
其中b.BranchID==a.Parent
选择b).Single()).Single();
Console.WriteLine(t.BranchID);//打印20
}
类上下文
{
public List BranchInfos=新列表();
}
类BranchInfo
{
公共字符串类型;
公共信息中心;
公共int家长;
}
枚举分支类型
{
服务=0
}
}
}

我相信以下内容相当于您的代码示例。我添加了一些模拟代码,将其转换为一个自包含的示例

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Context ctx = new Context();
            ctx.BranchInfos.Add(new BranchInfo() { Type = "NonService", BranchID = 20, Parent = 0 });
            ctx.BranchInfos.Add(new BranchInfo() { Type = "Service", BranchID = 21, Parent = 20 });
            ctx.BranchInfos.Add(new BranchInfo() { Type = "NonService", BranchID = 30, Parent = 20 });

            int branchId = 21;

            var t = (from a in ctx.BranchInfos
                     where a.BranchID == branchId
                     select a.Type != BranchType.Service.ToString() ? a :
                     (from b in ctx.BranchInfos
                      where b.BranchID == a.Parent
                      select b).Single()).Single();

            Console.WriteLine(t.BranchID); // Prints 20
        }

        class Context
        {
            public List<BranchInfo> BranchInfos = new List<BranchInfo>();
        }

        class BranchInfo
        {
            public string Type;
            public int BranchID;
            public int Parent;
        }

        enum BranchType
        {
            Service = 0
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
Context ctx=新上下文();
添加(new BranchInfo(){Type=“NonService”,branchhid=20,Parent=0});
添加(new BranchInfo(){Type=“Service”,BranchID=21,Parent=20});
添加(new BranchInfo(){Type=“NonService”,branchhid=30,Parent=20});
内衣