我有一个Linq表达式,我想插入到ADO.NET数据表中。 我想知道查询中字段的名称,以便设置数据表名称。 以下是我的代码示例:
var result=from item in context.table
select new{
field1=... ,
field2=... ,
field3=...
};
我想要做的是设置表名。
Datatable.Columns.Add("field1"); .. etc
我试图手动完成,但我相信应该有一个优雅的解决方案。
由于
答案 0 :(得分:4)
我的建议:
var result=from item in context.table
select new{
field1=... ,
field2=... ,
field3=...
};
static IEnumerable<string> GetPropertyNames<T>(IEnumberable<T> lst)
{
foreach (var pi in typeof(T).GetProperties())
{
yield return pi.Name;
}
}
var propnames = GetPropertyNames(result);
答案 1 :(得分:3)
通过使用反射,您可以提取在LINQ表达式中创建的匿名类型的属性名称。
var result = from item in context.table
select new {
field1 = ... ,
field2 = ... ,
field3 = ... };
if (result.Any())
{
Type t = result.First().GetType();
foreach (PropertyInfo p in t.GetProperties())
{
// Get the name of the prperty
Console.WriteLine(p.Name);
}
}
答案 2 :(得分:3)
这可能有点简单;)......
var fieldNames = (from p in query.GetType().GetProperties() select p.Name).ToArray();
答案 3 :(得分:2)
因为select new
创建了一个匿名类型,我所知道的并不是一个简短的优雅解决方案,但你可以做你想做的事。这里的想法是,您将获取查询返回的第一个项目,并使用匿名类型的类型信息,我们可以反映其属性并填充您的DataTable
。
我们可以使用以下方法执行此操作,该方法采用匿名类型的DataTable
和Type
信息。
public static void FillColumns(DataTable table, Type anonymousType) {
PropertyInfo[] properties = anonymousType.GetProperties();
foreach (PropertyInfo property in properties) {
table.Columns.Add(property.Name);
}
}
然后例如你可以做这样的事情
var result = from item in context.Table
select new {
field1 = item.f1,
field2 = item.f2,
field3 = item.f3
};
if (result.Count() != 0) {
DataTable table = new DataTable("Table");
FillColumns(table, result.First().GetType());
}
此简短示例中的DataTable
将产生3列field1
,field2
和field3
。
编辑已经投入了时间,所以不妨发布完整的工作示例。
namespace ConsoleApplication1
{
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
#region Fake Database
internal class DatabaseMock
{
private DatabaseMock() {
// Hides the default public constructor created by the compiler
// Uses the factory pattern for creation instead
}
/// <summary>
/// Creates a new instance of a database with three default items
/// </summary>
public static DatabaseMock Create() {
DatabaseMock database = new DatabaseMock();
List<ItemMock> items = new List<ItemMock>();
items.Add(new ItemMock("item1"));
items.Add(new ItemMock("item2"));
items.Add(new ItemMock("item3"));
database.Table = items;
return database;
}
/// <summary>
/// Gets the items in the database
/// </summary>
public IEnumerable<ItemMock> Table {
get;
private set;
}
}
internal struct ItemMock
{
/// <summary>
/// Initializes a new instance of the ItemMock class
/// </summary>
public ItemMock(string value) {
_value = value;
}
private string _value;
/// <summary>
/// Gets the items value
/// </summary>
public string Value {
get {
return _value;
}
}
}
#endregion
static class Program
{
/// <summary>
/// Takes the specified DataTable and anonymous type information, and populates the table with a new DataColumn per anonymous type property
/// </summary>
public static void FillColumns(DataTable table, Type anonymousType) {
PropertyInfo[] properties = anonymousType.GetProperties();
foreach (PropertyInfo property in properties) {
table.Columns.Add(property.Name);
}
}
static void Main() {
DatabaseMock database = DatabaseMock.Create();
var query =
from item in database.Table
select new {
field1 = item.Value,
field2 = item.Value,
field3 = item.Value
};
if (query.Count() != 0) {
DataTable table = new DataTable("Table");
FillColumns(table, query.First().GetType());
#if DEBUG
foreach (DataColumn column in table.Columns) {
Debug.WriteLine(column.ColumnName);
}
#endif
}
}
}
}