2011-02-10 14 views
3

テーブルを返すストアドプロシージャがあります。格納されたprocはlinq datacontextを介して呼び出されます。ストアドプロシージャから返されたテーブルから列名を取得する方法

それはうまく動作しますが、私はテーブルを元に戻しますが、実際に返された特定のセルに関連するタイトルも取得したいと考えています。

誰でもこれを行う方法を知っていますか?

ストアド・プロシージャ・コールは、のようです:

var table = DataContext.GetTable().ToList(); 

だから私はList<GetTable>を取得します。データは問題ありません。カラム名も必要です。

+0

列名を意味しますか?ストアドプロシージャを呼び出すコードを投稿できますか? – Oded

+0

可能な繰り返し:http://stackoverflow.com/questions/187357/linq-to-sql-datatable-rows0columnname-equivalent – apros

+0

@Odedコードを追加しました。はい、私は列名を意味しました。 –

答えて

5

あなたは使用反射が、これは

var columns = table.First(); 

var properties = (from property in columns.GetType().GetProperties() 
        select property.Name).ToList(); 

foreach (var property in properties) 
    Console.WriteLine(property); 

ます。また、ストアドプロシージャが複数の結果を持ってこれを設定することができますのでSystem.Data.Linq.Mapping Namespace

AttributeMappingSource mappping = new System.Data.Linq.Mapping.AttributeMappingSource(); 
var model = mappping.GetModel(typeof(MyDataContext)); 


MetaFunction function = model.GetFunction(typeof(MyDataContext).GetMethod("MyStoredProc")); 


foreach (var resultTypes in function.ResultRowTypes) 
{ 

    foreach (var column in resultTypes.DataMembers) 
    Console.WriteLine(column.Name); 

} 

メタモデルを使用することができます行うことができますそのケースを処理するので、おそらくより良い方法です。

+0

Doh、私は純粋な反射ソリューションに取り組んでいて、私のテストではうまくいき、やや頑丈でした。しかし、 'MetaModel'を使う方がはるかにいいです。あなたは、関連付けを除外し、代わりに(名前が変更された列の場合は) 'MappedName'を使用しなければならないことに気付きました。 –

1

エンティティタイプに対してリフレクションを試すことができます。私が知る限り、生成されたすべてのプロパティは、対応するColumnAttributeがある場合、テーブルの列に対応します。あなたはこれを試すことができます:メタモデルのコンラッドの使用を見ての光で

public static List<string> GetColumnNames<TEntity>(Table<TEntity> table) 
    where TEntity : class 
{ 
    return GetColumnNames(typeof(TEntity)); 
} 

public static List<string> GetColumnNames(DataContext context, string functionName) 
{ 
    var retType = context.GetType().GetMethod(functionName).ReturnType; 
    System.Diagnostics.Debug.Assert(retType.Name == "ISingleResult`1"); 
    return GetColumnNames(retType.GetGenericArguments().Single()); 
} 

public static List<string> GetColumnNames(Type entityType) 
{ 
    return (from p in entityType.GetProperties() 
      let columnAttribute = p.GetCustomAttributes(false) 
            .OfType<System.Data.Linq.Mapping.ColumnAttribute>() 
            .SingleOrDefault() 
      where columnAttribute != null 
      select columnAttribute.Name ?? p.Name) 
      .ToList(); 
} 

// usage: 
// from a function/procedure name 
var names1 = GetColumnNames(DataContext, "GetTable"); 
// or by entity type directly (the return type of the function/procedure) 
var names2 = GetColumnNames(typeof(GetTable)); 

が、私はこの思い付きました。関連付け(LINQ to SQLによって追加)は、テーブルから列名を取得するためにフィルタリングする必要があります。

public static List<string> GetColumnNames<TEntity>(Table<TEntity> table) 
    where TEntity : class 
{ 
    return new System.Data.Linq.Mapping.AttributeMappingSource() 
     .GetModel(table.Context.GetType()) 
     .GetTable(typeof(TEntity)) 
     .RowType 
     .DataMembers 
     .Where(dm => !dm.IsAssociation) 
     .Select(dm => dm.MappedName) 
     .ToList(); 
} 

public static List<string> GetColumnNamesMeta(DataContext context, string functionName) 
{ 
    var type = context.GetType(); 
    return new System.Data.Linq.Mapping.AttributeMappingSource() 
     .GetModel(type) 
     .GetFunction(type.GetMethod(functionName)) 
     .ResultRowTypes 
     .SelectMany(rrt => rrt.DataMembers 
           .Where(dm => !dm.IsAssociation) 
           .Select(dm => dm.MappedName)) 
     .ToList(); 
} 
+0

+1完全回答 –

関連する問題