【问题标题】:Create a CSV feed from a Model MVC从模型 MVC 创建 CSV 提要
【发布时间】:2018-02-12 18:50:57
【问题描述】:

我有一个模型的 ICollection,我需要从模型中选择某些字段并从模型中创建一个 CSV 文件。现在我正在对模型进行 foreach 并拉取字段,然后像这样对它们进行污染:

foreach(OrderComposite ord in orders)
{
   order += ord.Customer.EmailAddress.ToString() + "," + ord.OrderId.Value.ToString() + "," + ord.DateCreated.Value.ToString() + "," + ord.TotalSalePrice.Value.ToString() + "," + ord.TotalSaleTax.Value.ToString() + ",0,0," + ord.OrderStatus.ToString() + ",?,?,?,?" + ord.TotalDiscount.Value.ToString() + ",online";
}

这不是我想要的方式。我确信有一种方法可以通过 LINQ 执行此操作,但我在使 Order.Select 语句正常工作时遇到问题。我知道使用这种方法效率极低,所以我开始尝试:

using(var file = File.CreateText(settings.listrakProductFeed.ListrakOrderItemsFileLocation))
{
   file.WriteLine(orders.Select(x => string.Join(",",x.Customer.EmailAddress.ToString(), x.OrderId.Value.ToString())));
}

这样更有效率吗?最终我会使用 WriteLineAsync,但一步一步来。

谢谢。

【问题讨论】:

  • 这样更有效率吗?同样使用.Selectforeach 用于内存收集几乎相同,只是效率稍低 - 在大多数情况下无需真正担心。

标签: c# asp.net-mvc linq csv


【解决方案1】:

这是一个非常简单的分隔文件结果的实现

public enum DelimitedFileHeaderOptions
{
    IncludeHeader,
    DoNotIncludeHeader
}

public class DelimitedFileResult<T> : FileResult where T : class
{
    private const String DefaultFileName = "file.csv";
    private const String DefaultContentType = "text/csv";
    private const String DefaultDelimiter = ",";

    public DelimitedFileResult(IEnumerable<T> data, DelimitedFileHeaderOptions headerOption)
        : this(data, DefaultDelimiter, DefaultFileName, DefaultContentType, headerOption) { }

    public DelimitedFileResult(IEnumerable<T> data, String delimiter = DefaultDelimiter, String fileName = DefaultFileName, String contentType = DefaultContentType,
        DelimitedFileHeaderOptions headerOption = DelimitedFileHeaderOptions.IncludeHeader)
        : base(contentType)
    {
        _data = data;
        _delimiter = delimiter;
        FileDownloadName = fileName;
        _headerOption = headerOption;
    }

    protected override void WriteFile(HttpResponseBase response)
    {
        var builder = new StringBuilder();

        var properties = (from p in typeof (T).GetProperties() select p).ToList();
        var propertyNames = (from p in properties select p.GetDisplayName()).ToList();

        if (_headerOption == DelimitedFileHeaderOptions.IncludeHeader)
            builder.AppendLine(String.Join(_delimiter, propertyNames));

        foreach (T item in _data)
        {
            foreach (var property in properties)
            {
                builder.Append(property.GetValue(item, null));
                builder.Append(_delimiter);
            }

            builder.AppendLine();
        }

        response.Write(builder.ToString());
    }

    private readonly IEnumerable<T> _data;
    private readonly String _delimiter;
    private readonly DelimitedFileHeaderOptions _headerOption;
}
  1. 在 csv 文件中创建一个包含所需字段的类。
  2. 运行您的 linq 查询
  3. 将生成的 IEnumerable 传递给构造函数

它不做的事情。

使用属性值中的分隔符处理字符串。 嵌套类型。您应该自己扁平化数据。

但这些当然是您可以自己添加的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 2011-11-26
    相关资源
    最近更新 更多