Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.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的表现会更好吗?_C#_Performance_Linq_Datatable - Fatal编程技术网

C# LINQ的表现会更好吗?

C# LINQ的表现会更好吗?,c#,performance,linq,datatable,C#,Performance,Linq,Datatable,下面的方法选择管理权限并从缓存的数据表返回bool,使用Linq会更好吗 你可能会问为什么不测试一下。嗯,由于缺乏知识,我不能用Linq写 DataRow[] result = PrivilegeMap.Select("privilegeActionId=" + (int)actionId); bool moderatorHasIt = Convert.ToBoolean(result[0]["moderatorHasIt"]); bool ad

下面的方法选择管理权限并从缓存的数据表返回bool,使用Linq会更好吗

你可能会问为什么不测试一下。嗯,由于缺乏知识,我不能用Linq写

 DataRow[] result = PrivilegeMap.Select("privilegeActionId=" + (int)actionId);
            bool moderatorHasIt = Convert.ToBoolean(result[0]["moderatorHasIt"]);
            bool adminHasIt = Convert.ToBoolean(result[0]["adminHasIt"]);                                        
            if (myRole == User.Role.Admin)
            {
                return Convert.ToBoolean(adminHasIt);
            }
            if (myRole == User.Role.Moderator)
            {
                return Convert.ToBoolean(moderatorHasIt);
            }
            else
            {
                return false;
            }

您列出的代码不完整,因为未定义
myRole
变量


考虑到这一点,我建议将其写在switch语句中,然后继续,直到它被确定为一个问题。另外,(我认为)它更容易阅读。

您列出的代码不完整,因为未定义
myRole
变量


考虑到这一点,我建议将其写在switch语句中,然后继续,直到它被确定为一个问题。另外,它更易于阅读(在我看来)。

使用LINQ可能会更快,因为datatable不必解析查询字符串,但通过更改数据表示形式,您将获得最大的优势,以避免首先对datatable进行查询

创建一个表示您感兴趣的特权的
IDictionary
,由
actionId
键入。然后,当您需要进行查找时,只需返回
dict[actionId


无论如何,我怀疑这可能是一个过早优化的例子:您是否测试了您的程序并发现这段代码占了您处理时间的很大一部分?

使用LINQ可能会更快,因为datatable不必解析您的查询字符串,但您将通过改变数据表示形式以避免首先查询datatable

创建一个表示您感兴趣的特权的
IDictionary
,由
actionId
键入。然后,当您需要查找时,只需返回
dict[actionId

无论如何,我怀疑这可能是一个过早优化的例子:您是否测试了您的程序并发现这段代码占了您处理时间的很大一部分

让我们假设如下:

  • 基础表的起始大小、读取频率和更新频率之间的平衡是这样的:将整个表加载到内存中并反复查看它来替换它是没有意义的

  • 每个id只有一个匹配行

  • 这一行还有其他一些我们不关心的有趣的领域

  • 然后,如果我们用Linq2SQL
    替换PrivilegMap,则等效的LINQ代码将类似于:

    var result = PrivilegeMap.Where(p => p.PrivilegeActionId == actionID).Select(p => new{p.ModeratorHasIt, p.AdminHasIt}).First()
    if (myRole == User.Role.Admin)
    {
      return result.AdminHasIt;
    }
    if (myRole == User.Role.Moderator)
    {
      return result.ModeratorHasIt;
    }
    else
    {
      return false;
    }
    
    (就此而言,
    var result=PrivilegeMap.Where(p=>p.PrivilegeActionId==actionID)。首先(p=>new{p.mediatorhasit,p.AdminHasIt})
    也可以写成
    var result=(从PrivilegeMap中的p.PrivilegeActionId==actionID选择new{p.mediatorhasit,p.AdminHasIt})。第一()
    对于相同的LINQ操作,这只是一种不同的语法)

    假设
    actionID
    2
    您的代码将按照以下方式转换为SQL:

    从特权中选择*,其中privilegeActionId=2

    上述Linq将转换为:

    从Privileges WHERE privilegegeActionId中选择前1名adminHasIt、版主HasIt

    您可以看到,如果这是一个包含许多列的表和/或如果有多个匹配行,那么这可能会更加高效

    (如果PrivilegeMap是可枚举但不可查询的,那么它将变成一个操作,在这个操作中,整个内容都被加载和扫描,因此根本没有效率)

    但是,另一方面,生成SQL的代码可能更复杂,并且需要在设置特权实体对象时进行一些工作。如果这是一个一次性操作,那么无论从开发人员还是运行时效率来看,都不值得这样做,但除此之外,这两者都会受益

    但是,请注意,在这两种情况下,我们都在不必要地进行查询。实际上,我会将我的查询替换为:

    if (myRole == User.Role.Admin)
    {
      return PrivilegeMap.Where(p => p.PrivilegeActionId == actionID).Select(p => p.AdminHasIt).First();
    }
    if (myRole == User.Role.Moderator)
    {
      return PrivilegeMap.Where(p => p.PrivilegeActionId == actionID).Select(p => p.ModeratorHasIt);
    }
    else
    {
      return false;
    }
    
    它要么只查询adminHasIt,要么只查询moderatorHasIt,要么根本不查询,因为无论数据库状态如何,
    myRole
    的任何其他值都保证为false

    同样,您可以通过以下方式获得更简单的改进:

    if(myRole != User.Role.Admin && myRole != User.Role.Moderator)
      return false;
    DataRow[] result = PrivilegeMap.Select("privilegeActionId=" + (int)actionId);
    if (myRole == User.Role.Admin)
    {
      return Convert.ToBoolean(result[0]["adminHasIt"]);
    }
    if (myRole == User.Role.Moderator)
    {
      return Convert.ToBoolean(result[0]["moderatorHasIt"]);
    }
    
    在这里,如果我们不可能使用数据库查询,我们首先要完全避免数据库查询,只转换我们关心的字段,然后不将bool转换为bool。这种关于实际使用数据的局部思考更容易做到,虽然大多数这样的节省很小,但有些节省很大(这可能是)它们是习惯问题,而不是复杂的权衡问题。

    可能是这样

    让我们假设如下:

  • 基础表的起始大小、读取频率和更新频率之间的平衡是这样的:将整个表加载到内存中并反复查看它来替换它是没有意义的

  • 每个id只有一个匹配行

  • 这一行还有其他一些我们不关心的有趣的领域

  • 然后,如果我们用Linq2SQL
    替换PrivilegMap,则等效的LINQ代码将类似于:

    var result = PrivilegeMap.Where(p => p.PrivilegeActionId == actionID).Select(p => new{p.ModeratorHasIt, p.AdminHasIt}).First()
    if (myRole == User.Role.Admin)
    {
      return result.AdminHasIt;
    }
    if (myRole == User.Role.Moderator)
    {
      return result.ModeratorHasIt;
    }
    else
    {
      return false;
    }
    
    (就此而言,
    var result=PrivilegeMap.Where(p=>p.PrivilegeActionId==actionID)。首先(p=>new{p.mediatorhasit,p.AdminHasIt})
    也可以写成
    var result=(从PrivilegeMap中的p.PrivilegeActionId==actionID选择new{p.mediatorhasit,p.AdminHasIt})。第一()
    对于相同的LINQ操作,这只是一种不同的语法)

    假设
    actionID
    2
    您的代码将按照以下方式转换为SQL:

    从特权中选择*,其中privilegeActionId=2

    上述Linq将转换为:

    从Privile中选择前1名adminHasIt、主持人HasIt