2

テーブルをコンマ区切りの CSV ファイルに取得しようとしています。私は現在、次のようにそれを達成しています:

var csv = new StringBuilder("id,Name,Address,City,State\n");
var delimiter = ",";
var newline = "\n";

using (var db = MyDatabase())
{
     var query = from c in db.Customers select c;
     foreach(var q in query)
         csv.Append(q.id).Append(delimiter)
             .Append(q.name).Append(delimiter)
             .Append(q.address).Append(delimiter)
             .Append(q.city).Append(delimiter)
             .Append(q.state).Append(newline);
}

これにより、csv 罰金が作成されます。しかし、私の質問は、各列を個別に指定せずにこれを達成できるより合理的な方法はありますか? 場合によっては、 select allを実行したいのですが、テーブルに多数の列があるため、少しぎこちなく見えます。

4

3 に答える 3

3

CSV に書き込みたい各プロパティを指定せずにこれを行うには、リフレクションを使用する必要があります。これを行う方法の基本的な例を次に示します。

List<Customer> query = from c in db.Customers select c;
        foreach (var q in query)
        {
            Type type = typeof(Customer);
            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                string value = property.GetValue(type, null) != null
                    ? property.GetValue(type, null).ToString() 
                    : string.Empty; // or whatever you want the default text to be
                csv.Append(q.id).Append(delimiter);
            }
        }

これは、クエリから各 Customer をループし、Customer の各プロパティをループして値を書き込みます。これは、Customer からの各プロパティを CSV ファイルに書き込むことを前提としています。これにより、少なくとも、達成したいことを行う方法についてのアイデアが得られるはずです。

于 2012-07-09T05:56:48.557 に答える
1

あなたが達成したいことへの最短経路は次のようになります:

var props = typeof(Customer).GetProperties(
          BindingFlags.Instance|BindingFlags.Public
      );

StringBuilder result = new StringBuilder(
         (
             from prop in props select prop.Name
         ).Join(',') + "\n"
     );

Function<string,Customer> project = ( 
   Customer c => (
           from prop in props 
           select prop.GetValue(c).ToString()
       ).Join(",")+"\n";
)

using (var db = MyDatabase())
{
    var query = from c in db.Customers select project(c);
    foreach (var res in query) {
        result.append(res);
    }
}

簡単に一般化することができますが、型でのリフレクションの大量使用を避けるために、リフレクトされたPropertyInfoをキャッシュする必要があります。

警告:改行、カンマ、引用符などがCSVファイルを壊す可能性があるため、プロパティ値を適切にエスケープする必要があります。さらに良いことに、正しいCSVファイルの書き込みの問題にすでに対処しているライブラリを使用してください。

于 2012-07-09T06:14:38.747 に答える
1

私はこのコードを使用します:

string delimiter = "|";
string newLine = Environment.NewLine;

using (mCustDataContext = new CustDataContext()) {
    var props = typeof(Customer).GetProperties();

    StringBuilder headers = new StringBuilder(string.Join(delimiter, props.Select(c => c.Name).ToArray()) + newLine);

    Func<Customer, string> myFunc = c => 
         string.Join(delimiter, props.Select(b => b.GetValue(c,null))) + newLine;

    var query = mCustDataContext.Customers.Select(myFunc);

    foreach(var q in query)
        headers.Append(q);

    File.WriteAllText(yourFileName, headers.ToString(), mEncoding);
}
于 2013-04-15T04:32:28.407 に答える