有没有办法让SqlQuery或任何其他sql执行方法组成一个模型对象,并允许像Include这样的方法工作?我这样做(其中view_products是一个SQL表函数):
Sub ReadUpdatedFiles()
Application.ScreenUpdating = False
Dim fso As New FileSystemObject
Dim fld As Folder
Dim f As File
Dim MyPath As String
MyPath = "\\filepath\folder"
Dim lastModified As Date
lastModified = FileDateTime(ThisWorkbook.path)
Dim sheetExists As Boolean
Dim ws As Worksheet
Dim sheetName As String
Dim mybook As Workbook
Dim sheetCounter As Integer
Set fld = fso.GetFolder(MyPath)
For Each f In fld.Files
If f.Type = "CSV File" Then
If f.DateLastModified - lastModified > 0 Then
sheetExists = False
sheetName = Left(f.Name, InStr(f.Name, ".") - 1)
sheetCounter = 0
For Each ws In Worksheets
sheetCounter = sheetCounter + 1
If ws.Name = sheetName Then
sheetExists = True
End If
Next ws
Set mybook = Workbooks.Open(f.path)
If sheetExists Then
basebook.Sheets(sheetName).Delete
Else
sheetCounter = basebook.Sheets.Count
End If
mybook.Worksheets(1).Copy after:=ThisWorkbook.Sheets(sheetCounter)
End If
End If
Next f
Application.ScreenUpdating = True
End Sub
我想这样做:
var p = context.SqlQuery<Product>("select * from view_products(@param1)", new SqlParameter("param1", "somevalue"));
这让我得到了一个DbRawSqlQuery。我不能包含&#34;包括&#34;因为你不能在DbRawSqlQuery上这样做。所以,我最后添加一个AsQueryable,如:
var list = p.Include(i => i.Inventories).ToList();
但是,我知道这真的给了我一个IEnumerable,所以.Include不会产生任何结果。
我正在寻找另一种方法的建议,我从SQL函数中获取我的产品,然后加载相关的Inventory对象,以便我有一个对象图。谢谢!
答案 0 :(得分:1)
SqlQuery
提出了一些我尚未意识到的问题。
您正确解释了将Include
转换为IEnumerable
后IQueryable
没有任何效果的原因。 Include
扩展了一个表达式,IEnumerable
没有表达式(并且在将其转换为IQueryable
之后不会神奇地得到一个表达式。)
所以你最终得到的Product
列表没有附加到上下文而不能延迟加载。您必须明确地将Product
附加到上下文中(例如,将其状态设置为Unchanged
)以使其延迟加载。
这是我刚刚发现的,而且很奇怪。实体被实现为代理对象,但与DbSet.AsNoTracking()
提取的分离实体相反,它们不显示延迟加载。我认为这是一个错误,我报告了它。
但延迟加载会导致n + 1查询反模式:分别为每个产品获取Inventory对象的查询。因此,这不是获取对象图的最佳方式。
所以你真正想要的是一次性加载属于这些产品的所有Inventory对象,并让 relationship fixup 完成它的工作(即EF自动填充所有Product.Inventories
个集合):
context.Inventories.Where(i => productIds.Contains(i.ProductId)).Load();
...其中productIds
是p
中的产品ID列表。
但是,关系修正仅适用于附加实体,因此,您必须明确地将其状态更改为Unchanged
。如果你这样做,你就准备好了...除非你没有。
同样,DbSet.AsNoTracking()
提取的分离实体也存在差异。后者回应了关系修正,而SqlQuery
的关系没有!
剩下的就是:加载上面显示的相关Inventory
对象并自行填充Product.Inventories
个收藏集:
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();
}
当然这完全不能令人满意。