不同的结果LINQ vs' normal' C#代码

时间:2015-12-10 13:13:52

标签: c# linq

我正在抓住这个问题。我认为下面的代码应该产生相同的结果。但是,他们没有。我显然遗漏了一些东西。 LINQ查询返回的长度小于普通的C#代码。

CardView

当我针对相同的列表运行它们时:

GetListSizeForCurrentItems:2401408086
GetListSizeForCurrentItems2:2401408086
GetListSizeForItemVersions:459902667
GetListSizeForItemVersions2:459902667
GetListSize:459902667
GetListSize2:2842896668

重构代码以隔离上面的每个查询:

    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;
    }

对Concat()的更改肯定会改变结果。

额外的一双眼睛将是有益的。在将普通C#翻译成LINQ时我缺少什么。

2 个答案:

答案 0 :(得分:2)

我猜问题出在Union。它返回......(强调我的)

  

IEnumerable<T>包含两个输入序列中的元素,不包括重复项

因此,如果列表中有重复项,则只计算唯一值。请改用Concat

答案 1 :(得分:0)

在GetListSize2()中,你不检查long.TryParse是否返回false。

TryParse方法与Parse方法类似,不同之处在于,如果转换失败,TryParse方法不会抛出异常。如果s无效且无法成功,则无需使用异常处理来测试FormatException解析。

因此,如果列表中有一些非数字数据,则fileSize不会为0,但将是上一次迭代的文件大小。

更正将是:

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++)
            {
                if (long.TryParse(item.Versions[i]["File_x0020_Size"].ToString(), out fileSize) == false)
                    fileSize=0;
                byteSize += fileSize;
            }
        }
        else
        {
            if (long.TryParse(item["File_x0020_Size"].ToString(), out fileSize) == false)
                    fileSize=0;
            long.TryParse(item["File_x0020_Size"].ToString(), out fileSize);
            byteSize += fileSize;
        }
    }
    return byteSize;
}