Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在EntityFramework中使用SqlQuery组成一个真正的IQueryable_C#_Sql Server_Entity Framework - Fatal编程技术网

C# 在EntityFramework中使用SqlQuery组成一个真正的IQueryable

C# 在EntityFramework中使用SqlQuery组成一个真正的IQueryable,c#,sql-server,entity-framework,C#,Sql Server,Entity Framework,有没有办法让SqlQuery或任何其他sql执行方法组成一个模型对象,并允许像Include这样的方法工作?我正在这样做(其中view_products是一个SQL表函数): 这会给我一个DbRawSqlQuery。这是我不能“包含”的,因为在DbRawSqlQuery上不能这样做。因此,我在末尾添加了一个AsQueryable,如: var p = context.SqlQuery<Product>("select * from view_products(@param1)", n

有没有办法让SqlQuery或任何其他sql执行方法组成一个模型对象,并允许像Include这样的方法工作?我正在这样做(其中view_products是一个SQL表函数):

这会给我一个DbRawSqlQuery。这是我不能“包含”的,因为在DbRawSqlQuery上不能这样做。因此,我在末尾添加了一个AsQueryable,如:

var p = context.SqlQuery<Product>("select * from view_products(@param1)", new SqlParameter("param1", "somevalue")).AsQueryable<Product>();
var p=context.SqlQuery(“从视图中选择*产品(@param1)”,新的SqlParameter(“param1”,“somevalue”)).AsQueryable();
但是,我知道这确实给了我一个IEnumerable,所以.Include不会产生任何结果


我正在寻找另一种方法的建议,从SQL函数中获取产品,然后加载相关的库存对象,这样我就有了一个对象图。谢谢

SqlQuery
带来了一些我还没有意识到的问题

不包括 您正确地解释了为什么将
IEnumerable
转换为
IQueryable
后,
Include
没有任何效果
Include
扩展了一个表达式,而
IEnumerable
没有表达式(并且在将其转换为
IQueryable
后不会神奇地得到一个表达式)

没有连接就没有延迟加载 因此,您的
产品
列表没有附加到上下文,并且不能延迟加载。您必须将
产品
明确地附加到上下文中(例如,通过将其状态设置为
未更改
),使其延迟加载

这是我刚刚发现的,很奇怪。实体被物化为代理对象,但与通过
DbSet.AsNoTracking()
获取的分离实体相反,它们不显示延迟加载。我认为这是一个错误,我报告了它

但是延迟加载会导致n+1查询反模式:分别获取每个产品的库存对象的查询。所以这不是获取对象图的最佳方法

没有关系修复 因此,您真正想要的是一次性加载属于这些产品的所有库存对象,并让关系修复完成其工作(即EF自动填充所有
Product.Inventory
collections):

…其中,
productID
p
中的产品ID列表

但是关系修复只适用于连接的实体,所以同样,您必须显式地将它们的状态更改为
未更改。如果你这么做,你就准备好了。。。除非你不是

同样,通过
DbSet.AsNoTracking()
获取的分离实体也有区别。后者响应关系修复,来自
SqlQuery
的则不响应

(而是)详细的解决方案 所以剩下的是:加载上面显示的相关
库存
对象,并填充
产品。库存
集合:

var query = from product in p
            join inv context.Inventories.Local
                on product.ProductId equals inv.ProductId
                into inventories
            select new { product, inventories }
foreach(var anon in query)
{
    anon.product.Inventories = anon.inventories.ToList();
}

当然,这一切都很不令人满意。

恰到好处地使用where子句2将查询连接到两个表中。并从联接表中选择*作为导航属性name@Brandon赛德尔,这会让我得到我想要的数据,但不会填充对象图。我认为这是目前所能期望的最好结果。我将注意力转向摆脱SQL表函数,并在EF查询中完成这一切。谢谢你的建议!
var p = context.SqlQuery<Product>("select * from view_products(@param1)", new SqlParameter("param1", "somevalue")).AsQueryable<Product>();
context.Inventories.Where(i => productIds.Contains(i.ProductId)).Load();
var query = from product in p
            join inv context.Inventories.Local
                on product.ProductId equals inv.ProductId
                into inventories
            select new { product, inventories }
foreach(var anon in query)
{
    anon.product.Inventories = anon.inventories.ToList();
}