2011-02-10 4 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 для полного ответа –

Смежные вопросы