我正在使用Entity Framework 6。
我想运行一个返回非实体对象的存储过程(每行3个colunms)
using(var dbContext = new DBContextEntity())
{
var queryProducts = dbContext.Database.SqlQuery<DataTable>("dbo.GetProductByDesc @q", query);
}
如何将这些数据作为DataSet
或匿名对象获取,我可以迭代它?
答案 0 :(得分:3)
据我所知,EntityFramework不提供匿名对象实现。原因是它可能为每种类型生成IL代码并缓存它(或者只是进行简单的PropertyInfo缓存)。
解决方案是创建一个简单的类,其中包含与存储过程结果集的名称匹配的属性,并将此类用作SqlQuery的泛型参数。
编辑:
SqlQuery实现IEnumerable,当你迭代它时,它会在当前线程中自动执行。要迭代结果,您可以例如:
foreach(var product in queryProducts)
{
// do something with each product here
}
您还可以将产品类实例列表传递给期望它的函数:
ShowProducts(queryProducts.ToList());
您还可以在后台运行查询并在完成后返回Product列表,可以找到有关异步提取的更多信息here: http://www.codeguru.com/csharp/.net/net_framework/performing-asynchronous-operations-using-entity-framework.htm
答案 1 :(得分:1)
与@Too说的一样,最好定义一个POCO类,其属性对应于StoredProcedure或其他SQL语句返回的字段名和数据类型。
通常最好避免在您正在进行的任何新开发工作中使用DataSet。它们确实有其用途,但在POCO明显避免的高吞吐量情况下会有性能损失。
如果对DataSet的吸引力在于能够轻松地通过线路或文件将数据序列化以供以后使用,那么各种序列化框架将为您提供帮助,例如DataContractSerializer,Newtonsoft.Json等。
如果在PCL(可移植类库)中定义POCO,这也允许可移植性。
如果必须使用DataSet,我宁愿使用类型化的DataSet。在Too的答案中,DataRow可以用作POCO,因为它们有一个默认的构造函数。请注意在String以外的字段中使用null和它们的独特处理。