简体   繁体   中英

How to get column names from table returned from stored procedure

I have a stored procedure which returns a table. The stored proc is called via a linq datacontext.

It works fine and I get the table back however I really want to also get the title relating to each particular cell returned.

Does anyone know how to do this?

The stored procedure call is like:

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

So I get a List<GetTable> . The data is fine I just want the column names as well.

You can use reflection to do this

var columns = table.First();

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

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

You can also use the Meta Model in the 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);

}

Since Stored procedures can have more than one result set this is probably the better way since it handles that case.

You can try using reflection on the entity types. As far as I can tell, all generated properties correspond to the columns in the table if they have an associated ColumnAttribute . You can try this:

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));

In light of seeing Conrad's use of the meta model, I came up with this. Associations (added by LINQ to SQL) would need to be filtered out to get the column names from the table.

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM