Linq 将实体模型转换为数据集-可以这样做吗?
我在这里很沮丧。。。 对于.Net中的复杂问题,我通常可以在网络上的某个地方找到某种答案,但我无法找到这个答案。 我所处的场景是,我必须将LINQ to Entity查询的结果转换为数据集,这样数据就可以由现有业务逻辑处理,而我找不到一个解决方案 我尝试过一些基本的方法,比如EntityCommand生成读取器,但这一方法不起作用,因为DataTable.Load()执行了一个Exception(EntityCommand生成的读取器不支持GetSchemaTable() 我还尝试了更为友好的方法,比如实体到IDataReader(http://l2edatareaderadapter.codeplex.com/),但这一个抛出了异常,文档很少,而且自2008年以来从未被触及过 我发现的另一个方法是这里(http://blogs.msdn.com/b/alexj/archive/2007/11/27/hydrating-an-entitydatareader-into-a-datatable-part-1.aspx),但没有该守则的有效副本;只有片段 我发现很难相信,首先MS不会提供这种现成的向后兼容性项目,其次,它也不会由社区创建 如果有的话,我也愿意考虑商业解决方案Linq 将实体模型转换为数据集-可以这样做吗?,linq,datatable,dataset,entity,linq-to-dataset,Linq,Datatable,Dataset,Entity,Linq To Dataset,我在这里很沮丧。。。 对于.Net中的复杂问题,我通常可以在网络上的某个地方找到某种答案,但我无法找到这个答案。 我所处的场景是,我必须将LINQ to Entity查询的结果转换为数据集,这样数据就可以由现有业务逻辑处理,而我找不到一个解决方案 我尝试过一些基本的方法,比如EntityCommand生成读取器,但这一方法不起作用,因为DataTable.Load()执行了一个Exception(EntityCommand生成的读取器不支持GetSchemaTable() 我还尝试了更为友好的方
谢谢 这可能不是最好的解决方案,但是如果您的场景中只有一个或两个表需要添加到数据集中,为什么不直接手动构建它们呢
var result = db.YourTable; // get your Linq To Entities result.
DataSet ds = new DataSet();
DataTable tbl = new DataTable();
tbl.Columns.Add("col1", typeof(string));
tbl.Columns.Add("col2", typeof(int));
foreach (var r in result)
{
var row = tbl.NewRow();
row[0] = r.Col1;
row[1] = r.Col2;
tbl.Rows.Add(r);
}
ds.表格。添加(待定)
Col1和Col2来自Linq To Entity对象,您可以像这样创建所有需要的表并返回数据集。您可以将结果转换为列表,并使用以下命令将列表转换为数据表
public DataTable ConvertToDataTable<T>(IList<T> data)
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
foreach (PropertyDescriptor prop in properties)
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
foreach (T item in data)
{
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
table.Rows.Add(row);
}
return table;
}
公共数据表ConvertToDataTable(IList数据)
{
PropertyDescriptorCollection属性=
GetProperties(typeof(T));
DataTable=新的DataTable();
foreach(属性中的PropertyDescriptor属性)
table.Columns.Add(prop.Name,Nullable.GetUnderlyingType(prop.PropertyType)??prop.PropertyType);
foreach(数据中的T项)
{
DataRow行=table.NewRow();
foreach(属性中的PropertyDescriptor属性)
行[prop.Name]=prop.GetValue(项)??DBNull.Value;
table.Rows.Add(行);
}
返回表;
}
希望这有帮助
Preetam这是一个灵活的代码,可以满足您的大部分需求:
public DataTable LINQToDataTable<T>(IEnumerable<T> varlist)
{
DataTable dtReturn = new DataTable();
// column names
PropertyInfo[] oProps = null;
if (varlist == null) return dtReturn;
foreach (T rec in varlist)
{
// Use reflection to get property names, to create table, Only first time, others will follow
if (oProps == null)
{
oProps = ((Type)rec.GetType()).GetProperties();
foreach (PropertyInfo pi in oProps)
{
Type colType = pi.PropertyType;
if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
{
colType = colType.GetGenericArguments()[0];
}
dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
}
}
DataRow dr = dtReturn.NewRow();
foreach (PropertyInfo pi in oProps)
{
dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue
(rec, null);
}
dtReturn.Rows.Add(dr);
}
return dtReturn;
}
公共数据表LINQTODatable(IEnumerable varlist)
{
DataTable dtReturn=新DataTable();
//列名
PropertyInfo[]oProps=null;
if(varlist==null)返回dtReturn;
foreach(varlist中的T rec)
{
//使用反射来获取属性名,创建表,只有第一次,其他人会跟随
if(oProps==null)
{
oProps=((Type)rec.GetType()).GetProperties();
foreach(oProps中的属性信息pi)
{
类型colType=pi.PropertyType;
if((colType.IsGenericType)&&(colType.GetGenericTypeDefinition()==typeof(null)))
{
colType=colType.GetGenericArguments()[0];
}
dtReturn.Columns.Add(新数据列(pi.Name,colType));
}
}
DataRow dr=dtReturn.NewRow();
foreach(oProps中的属性信息pi)
{
dr[pi.Name]=pi.GetValue(rec,null)==null?DBNull.Value:pi.GetValue
(rec,空);
}
dtReturn.Rows.Add(dr);
}
返回数据返回;
}
Thx多米尼克。我试过类似的东西。一个巨大的问题——大型实体(即包含大量数据的实体)。为了解决这个问题,我使用了一个递归方法,沿着实体树向下,为它开始复制的每个新级别启动一个新的自身副本(在一个新线程中),但是猜猜看——DataTable对象不是线程安全的。它们的内部索引很容易损坏。当您尝试从多个线程向其中添加行时,就会出现如下异常。我不知道DataTable不是线程安全的。在这种情况下,我想最简单的方法是从SqlCommand填充数据集,而不是从实体传递。有趣的方法。我必须试一下,然后再给你回复。谢谢你的建议。