score:1

Accepted answer

I am sorry, I don't have working experience with LINQ.

This is purely based on looking at MSDN.

DataContext has a Mapping property, which returns an instance of MetaModel.
MetaModel has GetMetaType, which takes a Type. In your case it could be typeof(Project).
GetMetaType returns a MetaType which has the GetDataMember method, which takes a MemberInfo parameter. You will have to use reflection on your Projects object to get the MemberInfo object.
The MetaDataMember instance returned by GetDataMember should have all the things, you need.

I hope I am somewhat in right direction (purely looking at MSDN & traversing)

score:0

Your columns should be mapped as properties on your Project model. I'm not sure if you can get the underlying database structure when using LINQ to SQL. The entire point of LINQ to SQL is to abstract the database away.

score:3

Your Projects wrapper will have a set of properties each with a [Column] attribute. So just use reflection to enumerate the properties with that attribute.

score:6

Thanks guys, you got me started on the right track. I found my solution with the following code. I can then iterate through the DataMembers and pull out their individual properties such as name, type, etc.

var db = new GMPDataContext();
var columnNames = db.Mapping.MappingSource
                    .GetModel(typeof(GMPDataContext))
                    .GetMetaType(typeof(Project))
                    .DataMembers;

score:15

This would be nice to have as an extension method:

public static class LinqExtensions
{
  public static ReadOnlyCollection<MetaDataMember> ColumnNames<TEntity> (this DataContext source)
  {
      return source.Mapping.MappingSource.GetModel (typeof (DataContext)).GetMetaType (typeof (TEntity)).DataMembers;
  }
}

example:

var columnNames = myDataContext.ColumnNames<Orders> ();

score:2

Using Todd Smiths(+1) solution you get all properties (included entity sets, etc). To filter out all non-column properties this will do the trick:

var columnNames = db.ColumnNames<Orders>().Where(n => n.Member.GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute), false).FirstOrDefault() != null).Select(n => n.Name);

score:0

Here an another way:

        public string[] GetColumnNames()
        {
            var propnames = GetPropertyNames(_context.Users);
            return propnames.ToArray();
        }

        static IEnumerable<string> GetPropertyNames<T>(IEnumerable<T> lst)
        {
            foreach (var pi in typeof(T).GetProperties())
            {
                yield return pi.Name;
            }
        }

Related Articles