【发布时间】:2015-12-10 21:47:06
【问题描述】:
我在这方面摸不着头脑。我认为下面的代码应该产生相同的结果。然而,他们没有。我显然错过了一些东西。 LINQ 查询返回一个比普通 C# 代码小的 long。
public static long GetListSize(SPList list)
{
long longInt = 0;
long byteSize = (from item in list.Items.OfType<SPListItem>()
where item.ParentList.EnableVersioning == false
select long.TryParse(item["File_x0020_Size"].ToString(), out longInt) ? longInt : 0)
.Concat(from iItem in list.Items.OfType<SPListItem>()
where iItem.ParentList.EnableVersioning == true && iItem.Versions.Count > 1
from vItem in iItem.Versions.OfType<SPListItemVersion>()
select long.TryParse(vItem["File_x0020_Size"].ToString(), out longInt) ? longInt : 0)
.Sum();
return byteSize;
}
public static long GetListSize2(SPList list)
{
long byteSize = 0;
long fileSize = 0;
foreach (SPListItem item in list.Items)
{
if (item.ParentList.EnableVersioning == true && item.Versions.Count > 1)
{
for (int i = 0; i < item.Versions.Count; i++)
{
long.TryParse(item.Versions[i]["File_x0020_Size"].ToString(), out fileSize);
byteSize += fileSize;
}
}
else
{
long.TryParse(item["File_x0020_Size"].ToString(), out fileSize);
byteSize += fileSize;
}
}
return byteSize;
}
当我针对同一个列表运行它们时:
GetListSizeForCurrentItems:2401408086
GetListSizeForCurrentItems2:2401408086
GetListSizeForItemVersions:459902667
GetListSizeForItemVersions2:459902667
获取列表大小:459902667
GetListSize2: 2842896668
重构代码以隔离上述每个查询:
public static long GetListSizeForItemVersions(SPList list)
{
long longInt = 0;
long byteSize = (from iItem in list.Items.OfType<SPListItem>()
where iItem.ParentList.EnableVersioning == true && iItem.Versions.Count > 1
from vItem in iItem.Versions.OfType<SPListItemVersion>()
select long.TryParse(vItem["File_x0020_Size"].ToString(), out longInt) ? longInt : 0)
.Sum();
return byteSize;
}
public static long GetListSizeForItemVersions2(SPList list)
{
long byteSize = 0;
long fileSize = 0;
foreach (SPListItem item in list.Items)
{
if (item.ParentList.EnableVersioning == true && item.Versions.Count > 1)
{
for (int i = 0; i < item.Versions.Count; i++)
{
long.TryParse(item.Versions[i]["File_x0020_Size"].ToString(), out fileSize);
byteSize += fileSize;
}
}
}
return byteSize;
}
public static long GetListSizeForCurrentItems(SPList list)
{
long longInt = 0;
long byteSize = (from item in list.Items.OfType<SPListItem>()
where item.ParentList.EnableVersioning == false
select long.TryParse(item["File_x0020_Size"].ToString(), out longInt) ? longInt : 0)
.Sum();
return byteSize;
}
public static long GetListSizeForCurrentItems2(SPList list)
{
long byteSize = 0;
long fileSize = 0;
foreach (SPListItem item in list.Items)
{
long.TryParse(item["File_x0020_Size"].ToString(), out fileSize);
byteSize += fileSize;
}
return byteSize;
}
对 Concat() 的更改肯定会改变结果。
多一双眼睛会有好处。在将普通的 C# 转换为 LINQ 时我缺少什么。
【问题讨论】:
-
除了使用 Union 而不是 Concat 之外,您还在查询的第一部分中包含 EnableVersioning==false 值,而在您的普通 C# 代码中,您仅使用“else”让单个项目占总和的一个部分。
-
嗨,乔恩,关于 else(和 Union/Concat),你是对的。但是,如果我使用 EnableVersioning == false 将 where 子句添加到查询的第一部分,我会得到相当大的结果差异。我将更新问题以反映现在正在发生的事情。
-
请注意,如果您可以提供一个简短但 完整 的示例,并删除任何无关的内容(如字符串解析 - 您确定这是甚至需要?)
-
对于一个项目 ParentList.EnableVersioning 是否有可能在版本数为 1 的情况下为真?如果是,那么 GetListSize2 会做错事。如果
item.ParentList.EnableVersioning == false || item.Versions.Count <= 1,则执行GetListSize2中的else部分。