简体   繁体   English

如何使用一致的语法重写此LINQ表达式?

[英]How do I rewrite this LINQ expression using consistent syntax?

This one-statement query says neatly "Give me a list of bare filenames for which the file is a ZIP repository containing a certain file structure." 这个单语句查询整齐地说“给我一个裸文件名列表,该文件是一个包含特定文件结构的ZIP存储库。”

But I use both a .Where() extension method (fluent syntax) and a select query, because anything else I try fails to compile. 但我同时使用.Where()扩展方法(流畅的语法)和一个select查询,因为我尝试的其他任何东西都无法编译。 If I change ".Where(file ==> <statement>)" to "where <statement>", I get an error that the anonymous method code does not return a bool, and if I change the "select <clause>" to ".Select(<clause>)", the error is "No select clause is used." 如果我将“.Where(file ==> <statement>)”更改为“where <statement>”,我会收到一条错误,即匿名方法代码没有返回bool,如果我更改了“select <clause>” “.Select(<clause>)”,错误是“没有使用select子句”。

I'm happy with either query or fluent syntax, but I'd like to settle on one or the other. 我对查询或流利的语法感到满意,但我想解决其中一个问题。 Can anyone explain why this does not work, and what I would need to do to settle on one consistent syntax? 任何人都可以解释为什么这不起作用,以及我需要做什么来解决一个一致的语法?

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();

Since I don't have all type you're using in this expression it's quite hard to compile it but I think i should work like that: 因为我没有你在这个表达式中使用的所有类型,所以编译它很难,但我想我应该这样工作:

            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());

除了将select的使用更改为Select(file =>你还需要在开始时删除from file in 。然后你将删除使用那个查询语法select子句。这是单独from子句导致你看到的错误。 from [...] in子句中的每个都需要匹配的select

I'm happy with either query or fluent syntax, but I'd like to settle on one or the other. 我对查询或流利的语法感到满意,但我想解决其中一个问题。 Can anyone explain why this does not work, and what I would need to do to settle on one consistent syntax? 任何人都可以解释为什么这不起作用,以及我需要做什么来解决一个一致的语法?

It's not working very well for you because LINQ was not really made to handle large blocks of complex logic as criteria. 它对您来说效果不佳,因为LINQ并不是真正用来处理大块复杂逻辑作为标准。 LINQ Expression syntax, in particular, makes the assumption that you are going to provide Expressions (not Blocks), so it doesn't directly support multi-line statements. 特别是LINQ表达式语法假设您将提供表达式(而不是块),因此它不直接支持多行语句。

If you simply remove the from portion of your query, you can easily get method syntax to work, as ISun shows you how to do . 如果您只是删除查询的from部分,则可以轻松获取方法语法,因为ISun会向您显示如何操作

On the other hand, your code will be much more understandable and modular if you simply extract your anonymous method out, as @Servy suggested in comments. 另一方面,如果您只是提取匿名方法,您的代码将更容易理解和模块化,正如@Servy在评论中建议的那样。 In that case, you could either decide to say where FileHasMatchingZipStructure(file) . 在这种情况下,您可以决定说出where FileHasMatchingZipStructure(file) or .Where(FileHasMatchingZipStructure) , as you like. .Where(FileHasMatchingZipStructure) ,如你所愿。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM