2008-12-11 86 views
3

我期待获得从模型返回的列名称列表。任何人都知道如何做到这一点,任何帮助将不胜感激。如何从模型LINQ获取列名?

示例代码:

var project = db.Projects.Single(p => p.ProjectID.Equals(Id)); 

此代码将返回项目对象,我怎么会得到这个模型中的所有列名的列表。

谢谢

回答

1

对不起,我没有LINQ的工作经验。

这完全基于查看MSDN。

DataContext有一个Mapping属性,它返回一个MetaModel的实例。
MetaModelGetMetaType,需要Type。在你的情况下,它可能是typeof(Project)
GetMetaType返回一个MetaType其中有GetDataMember方法,其中需要MemberInfo参数。您将不得不在Projects对象上使用反射来获取MemberInfo对象。
MetaDataMemberGetDataMember返回的实例应该拥有所有你需要的东西。

我希望我有些在正确的方向(纯粹看MSDN &穿越)

+0

除了`MetaType.GetDataMember(MemberInfo)`,您可以使用[`MetaType.PersistedDataMembers`](http://msdn.microsoft.com/zh-cn/library/ system.data.linq.mapping.metatype.persistentdatamembers.aspx),它返回[`MetaDataMember`]的集合(http://msdn.microsoft.com/en-us/library/system.data.linq.mapping.metadatamember .aspx)对象,它具有你需要的Name,MappedName,IsPrimaryKey等属性,然后你就不需要Reflection了PersistedDataMembers只返回持久化的属性,而DataMembers会给你所有的属性。 – 2011-10-20 04:35:58

0

您的列应该被映射为项目模型中的属性。我不确定在使用LINQ to SQL时是否可以获得底层数据库结构。 LINQ to SQL的全部要点是将数据库抽象出来。

3

您的项目包装将有一组属性,每个属性都有一个[Column]属性。所以只需使用反射来枚举具有该属性的属性即可。

+0

我不明白为什么这么多的解决方案,使用反射。 Scott Gu将IQueryable转换为DataTable的解决方案使用反射从TableAttribute装饰的表实体中构建模式。我宁愿“选择TOP 0(field1,field2,...)FROM myTable“并执行datareader作为数据表。 – IAbstract 2010-09-18 22:37:46

6

谢谢你们,你让我开始在正确的轨道上。我用下面的代码找到了我的解决方案。然后我可以通过数据成员迭代和拉出它们各自的性质,例如名称,类型等

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

太棒了...我会用这个的。 – IAbstract 2010-09-18 22:39:39

+0

我刚刚翻译成VB.NET并且工作。如果有人想在VB中使用:myData.Mapping.MappingSource()。GetModel(GetType(NameOfYourDataContextObject))。GetMetaType(GetType (TableObjectFromDataContext).DataMembers – bernie2436 2011-12-16 18:24:39

15

这将是很好有作为一个扩展方法:

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

例如:

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

这是一个更好的解决方案t韩使用反射。 :) – IAbstract 2010-09-18 22:39:15

2

使用Todd Smiths(+1)解决方案,您可以获得所有属性(包括实体集等)。 过滤掉所有非列的属性,这将这样的伎俩:

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

这里的另一种方式:

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