C# 将LINQ结果写入文本文件

C# 将LINQ结果写入文本文件,c#,linq,C#,Linq,我正在尝试将LINQ查询的输出写入文本文件。为此,我使用了一种扩展方法 这是我的LINQ查询: var group = from c in census_data group c by c.state into g join s in state_gdp on g.FirstOrDefault().state equals s.state orderby s.gdp descending select new { State = g

我正在尝试将LINQ查询的输出写入文本文件。为此,我使用了一种扩展方法

这是我的LINQ查询:

var group =
    from c in census_data
    group c by c.state into g
    join s in state_gdp on g.FirstOrDefault().state equals s.state
    orderby s.gdp descending
    select new
    {
        State = g.Key,
        Count = g.Count(),
        SavingsBalance = g.Average(x => x.savingsBalanceDouble),
        GDP = s.gdp
    };
这是我的扩展方法:

public static class CSVWriter
{
    public static void write(this Enumerable e, string file)
    {
        using (System.IO.StreamWriter f = new System.IO.StreamWriter(file))
        {
            foreach (var i in e)
            {
                f.WriteLine(i);
            }
        }
    }
}

但是,我收到一个错误,该错误表示
System.Linq.Enumerable
没有
getEnumerator
方法。

可能的解决方案如下所示:

var result =
    from c in census_data
    group c by c.state into g
    join s in state_gdp on g.FirstOrDefault().state equals s.state
    orderby s.gdp descending
    select new
    {
        State = g.Key,
        Count = g.Count(),
        SavingsBalance = g.Average(x => x.savingsBalanceDouble),
        GDP = s.gdp
    };

var buffer = new StringBuilder();
buffer.AppendLine("#key,name,sum,gdp");
result.ToList().ForEach(item => buffer.AppendLine(String.Format("{0},{1},{2},{3}", item.State, item.Count, item.SavingBalance, item.GDP)));
File.WriteAllText("d:\\temp\\file.csv", buffer.ToString());
public static class CSVWriter
{
    public static void write<T>(this IEnumerable<T> e, string file)
    {
        using (System.IO.StreamWriter f = new System.IO.StreamWriter(file))
        {
            foreach (var i in e)
            {
                f.WriteLine(i);
            }
        }
    }
}
result.write<object>(file);
public class Placeholder
{
    public String Name { get; set; }
    public Int32 Index { get; set; }
    public Double Sum { get; set; }
}

您需要将
Enumerable
更改为
IEnumerable
。由于您正在创建一个匿名对象,您的解决方案将把匿名对象列表(
IEnumerable
)传输到您的函数中,在该函数中您将数据写入文件,但您将无法按照需要格式化输出

一种可能的解决方案是将要写入文件的行放入字符串缓冲区,然后使用System.IO.file.WriteAllText方法立即写入文本:

// test data
var data = new List<Int32> { 1, 20, 30, 40, 50, 70 };
// create a list of anonymous objects
var result = data.Select (d => new 
{
    Count = d,
    State = String.Format("Item {0}", d),
    SavingBalance = d * 10
});
// create the output text buffer
var buffer = new StringBuilder();
// add header line
buffer.AppendLine("#key,name,sum");
// add each result line
result.ToList().ForEach(item => buffer.AppendLine(String.Format("{0},{1},{2}", item.Count, item.State, item.SavingBalance)));
// write to file
File.WriteAllText("d:\\temp\\file.csv", buffer.ToString());
@aravol和@StephenneKennedy提到的解决方案如下所示:

var result =
    from c in census_data
    group c by c.state into g
    join s in state_gdp on g.FirstOrDefault().state equals s.state
    orderby s.gdp descending
    select new
    {
        State = g.Key,
        Count = g.Count(),
        SavingsBalance = g.Average(x => x.savingsBalanceDouble),
        GDP = s.gdp
    };

var buffer = new StringBuilder();
buffer.AppendLine("#key,name,sum,gdp");
result.ToList().ForEach(item => buffer.AppendLine(String.Format("{0},{1},{2},{3}", item.State, item.Count, item.SavingBalance, item.GDP)));
File.WriteAllText("d:\\temp\\file.csv", buffer.ToString());
public static class CSVWriter
{
    public static void write<T>(this IEnumerable<T> e, string file)
    {
        using (System.IO.StreamWriter f = new System.IO.StreamWriter(file))
        {
            foreach (var i in e)
            {
                f.WriteLine(i);
            }
        }
    }
}
result.write<object>(file);
public class Placeholder
{
    public String Name { get; set; }
    public Int32 Index { get; set; }
    public Double Sum { get; set; }
}
然后更改LINQ查询以创建新的
占位符对象,而不是匿名对象:

// test data
var data = new List<Int32> { 1, 20, 30, 40, 50, 70 };
var result = data.Select (d => new Placeholder
{
    Key = d,
    Name = String.Format("Item {0}", d),
    Sum = d * 10.0m
}).ToList();
result.write<Placeholder>("d:\\temp\\file.csv");
//测试数据
var数据=新列表{1,20,30,40,50,70};
var结果=数据。选择(d=>新占位符
{
键=d,
Name=String.Format(“项{0}”,d),
总和=d*10.0m
}).ToList();
结果.写入(“d:\\temp\\file.csv”);
扩展方法可以直接使用
write(this IEnumerable…
或强制转换每个对象以使用类属性:

public static class CSVWriter
{
    public static void write<T>(this IEnumerable<T> e, string file)
    {
        using (System.IO.StreamWriter f = new System.IO.StreamWriter(file))
        {
            foreach (var i in e)
            {
                f.WriteLine(((Placeholder)i).Sum);
            }
        }
    }
}
公共静态类CSVWriter
{
公共静态无效写入(此IEnumerable e,字符串文件)
{
使用(System.IO.StreamWriter f=new System.IO.StreamWriter(文件))
{
foreach(e中的var i)
{
f、 写线(((占位符)i).Sum;
}
}
}
}

“您的解决方案将不起作用,因为您无法将匿名对象列表(IEnumerable)传输到将数据写入文件的函数中。”是的,您可以,我的示例就是这样做的-编译器足够聪明,可以接受匿名T。问题是没有ToString()可在匿名对象上创建所需的输出。我喜欢您的第一个解决方案。但是如何选择每个条目属性(状态、计数等)?因为在你的测试数据中只有一个整数列表,但我的数据不是这样,我已经更新了我的答案。看看结果的创建,而不是列表。我在结果中为示例明确选择了三种不同的数据类型,以模拟您的情况。然后仔细查看将文本附加到缓冲区的行。
String.Format
自动将每个参数转换为字符串。因为您正在向文本文件写入,所以这是可以的。该列表仅用于模拟结果的创建。您需要的部分实际上只是创建缓冲区,填充缓冲区的部分,以及如何将缓冲区写入文件。在您的例子中,您应该编写
group.ToList()…
。我的意思是,您从整数列表创建了结果列表。但我的原始数据是一个IEnumerable。如何将数据提取到结果变量中,就像处理整数列表一样?我的意思是如何做
var result=data.Select(d=>new{Count=d,State=String.Format(“Item{0}”,d),SavingBalance=d*10})用于
IEnumerable
?在你的列表中,
d
只是一个整数,但对我来说不是。如何访问每个属性并将其值分配给适当的键?