4

这个单语句查询简洁地说“给我一个裸文件名列表,该文件是包含特定文件结构的 ZIP 存储库。”

但我同时使用 .Where() 扩展方法(流利的语法)和选择查询,因为我尝试的任何其他方法都无法编译。如果我将“.Where(file ==> <statement>)”更改为“where <statement>”,则会收到匿名方法代码不返回布尔值的错误,如果我更改“select <clause>”到“.Select(<clause>)”,错误是“没有使用选择子句”。

我对查询或流利的语法都很满意,但我想选择其中一个。谁能解释为什么这不起作用,以及我需要做些什么来确定一种一致的语法?

return (from file in Directory.EnumerateFiles(
                    Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), Globals.CompanyName, ProjectName, FolderName),
                    imageExtension,
                    SearchOption.TopDirectoryOnly)
    .Where(file =>
    {
        try
        {
            string relativePath = ClassFru.Station + "/";   // Inside ZIPs, paths use a single forward slash
            var zip = new ZipFile();
            zip.ZipError += (s, o) => { throw new Exception(); };
            using (zip = ZipFile.Read(file))
            {
                /// <todo>if (zip.Comment != Globals.CompanyName) { return false; }</todo>
                foreach (var fru in this.gFrus)
                {
                    var fruPath = relativePath + fru.Id + '.';
                    if (!(from e in zip where !e.IsDirectory && e.FileName.StartsWith(fruPath) select true).Any()) { return false; }
                }
                return true;
            }
        }
        catch (Exception)
        {
            return false;
        }
    })
    select Path.GetFileNameWithoutExtension(file)).ToArray();
4

3 回答 3

3

由于我没有您在此表达式中使用的所有类型,因此很难编译它,但我认为我应该这样工作:

            return (Directory.EnumerateFiles(
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
                Globals.CompanyName, ProjectName, FolderName),
            imageExtension,
            SearchOption.TopDirectoryOnly)
            .Where(file => {
                try
                {
                    string relativePath = ClassFru.Station + "/"; // Inside ZIPs, paths use a single forward slash
                    var zip = new ZipFile();
                    zip.ZipError += (s, o) => {
                        throw new Exception();
                    };
                    using (zip = ZipFile.Read(file))
                    {
                        /// <todo>if (zip.Comment != Globals.CompanyName) { return false; }</todo>
                        foreach (var fru in this.gFrus)
                        {
                            var fruPath = relativePath + fru.Id + '.';
                            if(zip.Any(e=> !e.IsDirectory && e.FileName.StartsWith(fruPath))
                                    .Any())
                            {
                                return false;
                            }
                        }
                        return true;
                    }
                } catch (Exception)
                {
                    return false;
                }
            }).Select(Path.GetFileNameWithoutExtension).ToArray());
于 2013-10-22T20:07:59.490 回答
1

除了改变使用selecttoSelect(file =>你还需要from file in在开始时去掉。然后,您将删除该查询语法select子句的使用。正是那个单独的from子句导致了您所看到的错误。每个from [...] in子句都需要一个匹配的select.

于 2013-10-22T20:08:52.207 回答
0

我对查询或流利的语法都很满意,但我想选择其中一个。谁能解释为什么这不起作用,以及我需要做些什么来确定一种一致的语法?

它对你来说不是很好,因为 LINQ 并不是真正用来处理大块复杂逻辑作为标准的。特别是 LINQ 表达式语法假设您将提供表达式(而不是块),因此它不直接支持多行语句。

如果您只是删除from查询的一部分,您可以轻松地让方法语法起作用,正如ISun 向您展示的那样

另一方面,如果您像@Servy 在评论中建议的那样简单地提取匿名方法,您的代码将更加易于理解和模块化。在这种情况下,您可以决定说where FileHasMatchingZipStructure(file)。或者.Where(FileHasMatchingZipStructure),如你所愿。

于 2013-10-22T20:44:21.400 回答