它可能是。
假设如下:
基础表的起始大小、读取频率和更新频率之间的平衡使得将整个内容全部加载到内存中并反复查看是没有意义的。
每个 id 只有一个匹配行。
行中有很多其他有趣的字段,我们在这里不关心。
如果我们用 Linq2SQL Table<Privileges> 替换 PrivilegeMap,等效的 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).First(p => new{p.ModeratorHasIt, p.AdminHasIt}) 也可以写成var result = (from p in PrivilegeMap where p.PrivilegeActionId == actionID select new{p.ModeratorHasIt, p.AdminHasIt}).First(),这只是相同 LINQ 操作的不同语法)。
假设actionID 是2
您的代码将按照以下方式转换为 SQL:
SELECT * FROM Privileges WHERE privilegeActionId=2
上面的 Linq 会变成:
SELECT TOP 1 adminHasIt, moderatorHasIt FROM Privileges WHERE privilegeActionId
您可以看到,如果这是一个包含很多列的表和/或如果有多个匹配行,那么这可能会更有效率。
(如果 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。这种对实际使用数据的本地思考要容易得多,虽然大多数这样的节省很小,但有些很大(这可能是),它们是一种习惯问题,而不是复杂的权衡。