1

最近、アプリケーション全体をローカライズしましたが、次の問題に直面しています。アプリケーションに次の LINQ クエリがあります。

var ccsum = from a in dtSumGL2.AsEnumerable()
    group Math.Abs(a.Field<double>(strpcPSPassBegCost)) by new 
    {
       BaseCC = a.Field<string>(strpcBaseCC)
    }
       into g
       select new
       {
          g.Key.BaseCC,
          PSPassBegCost = g.Sum()
       };

これは、SQL Server データベースccsumを作成し、その後データを入力するために使用する新しいオブジェクトを作成しています。DataTable

DataTable問題は、列名BaseCCおよびで作成される新しいアイテムのそれぞれが、PSPassBegCostこれらの名前がこれらの名前のドイツ語版と一致しないことです。今私の質問のために:次のようなことをする方法はありますか:

var ccsum = from a in dtSumGL2.AsEnumerable()
    group Math.Abs(a.Field<double>(strpcPSPassBegCost)) by new 
    {
       BaseCC = a.Field<string>(strpcBaseCC)
    }
       into g
       select new
       {
          g.Key.BaseCC as Resources.BaseCC,
          PSPassBegCost = g.Sum() as Resources.PSPassBegCost 
       };

ローカライズされた名前に従ってテーブルに名前を付けることができますか?


編集。DataTableから取得するコードccsum

fooDt = Utils.LINQToDataTable(ccsum);

public static DataTable LINQToDataTable<T>(IEnumerable<T> varlist)
{

    DataTable dtReturn = new DataTable();
    PropertyInfo[] oProps = null;
    if (varlist == null) 
    return dtReturn;

    foreach (T rec in varlist)
    {
        // Use reflection to get property names, to create 
        // table, Only first time, others will follow.
        if (oProps == null)
        {
            oProps = ((Type)rec.GetType()).GetProperties();
            foreach (PropertyInfo pi in oProps)
            {
                Type colType = pi.PropertyType;
                if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                {
                    colType = colType.GetGenericArguments()[0];
                }
                dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
            }
        }

        DataRow dr = dtReturn.NewRow();
        foreach (PropertyInfo pi in oProps)
        {
            pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue(rec, null);
        }
        dtReturn.Rows.Add(dr);
    }
    return dtReturn;
}

御時間ありがとうございます。

別のアプローチは、オブジェクトの「列」の名前ccsumを後処理ステップとして変更することですが、値はsumcc実行時に要求されるまで入力されません-他のアイデアはありますか?

4

3 に答える 3

2

列インデックスを読み取り可能な名前にマップするクラスまたは列挙型を作成します。

public static class SumGLColumn
{
    public const int BaseCC = 0;
    public const int PSPassBegCost = 1;
}

また、列名の代わりに列インデックスを使用して、データテーブルをクエリします。

var ccsum = from a in dtSumGL2.AsEnumerable()
            group Math.Abs(a.Field<double>(SumGLColumn.PSPassBegCost)) 
                  by a.Field<string>(SumGLColumn.BaseCC) into g
            select new {
               BaseCCg = g.Key,
               PSPassBegCost = g.Sum()
            };
于 2013-08-01T11:28:16.597 に答える
2

人間の理解を深めるためにシステムのコンポーネントをローカライズしようとすることは称賛に値する目標ですが、ツールやライブラリの大部分を使用する際に課題が生じます。一般に、データベース ツールでは、これらが一定であり、ローカリゼーションを無視していることを期待しています。

データベース テーブルを理解しやすくしたい場合、より実用的な解決策は、代わりにローカライズされたビューを作成することでしょうか? ビューはdeスキーマに存在し、テーブルを 1 対 1 に変換することができます。これにより、多くの標準ツールを活用して、システムを内部で一貫した「ニュートラル」な文化に保ち (開発文化が何であれ)、必要に応じてこれらの上に翻訳を提供できます。

この種のローカリゼーションをシステムの心臓部に埋め込もうとすることは、ほとんどの開発者やツールセットの期待を回避するためのコストに見合わない可能性が高く、ファサードを提供する方がよいと思います。

于 2013-08-01T11:37:46.213 に答える
1

これは不可能です。select ステートメントでは、匿名型を定義します。これは言語機能ではなく、コンパイラ機能です。つまり、コンパイラは、定義したプロパティを使用してこの型のクラスを作成します。

これは、コンパイラがコンパイル時に名前を認識している必要があることを意味します。より動的なものが必要な場合は、辞書を使用することをお勧めします。

select new Dictionary<string, object> 
{ 
    { Resources.BaseCC, g.Key.BaseCC },
    { Resources.PSPassBegCost , g.Sum() }
};
于 2013-08-01T11:15:13.377 に答える