我有一个应用程序利用实体框架5数据库优先,VB.net,Linq,SQL Server 2008 R2和断开存储库模式。从断开的EF5实现“友好”实体上下文
我已经使用了EF5.x的dbContext生成器来创建我的POCO并修改了T4模板来添加各种额外的位和bobs,包括我的INotifiyPropertyChanged事件提升。
我有各种链接表,我需要以“友好”的方式显示数据。
作为一个例子,我有以下两个表格;
颜色:
Colour_ID | Colour_Name | Created_By | Creation_Date | Modified_By | Modification_Date
----------------------------------------------------------------------------------------------
1 | Blue | 1 | 22-01-13 | 1 | 23-01-13
用户:
User_ID | First_Name | Last_Name |
--------------------------------------
1 | Peter | Gallagher |
为了在我的DataGrid中显示的 “友谊赛资料”,我拉中的数据,并创建“友好实体“使用代码,如;
Using CriticalPathDBContext As CriticalPathEntities = ConnectToDatabase()
Dim query = (From Colour In CriticalPathDBContext.Colours _
.Include(Function(x) x.CreationUser) _
.Include(Function(x) x.LastUpdateUser).AsNoTracking.ToList
Select New FriendlyColours With {.CreatedBy = If(Colour.CreationUserCode Is Nothing, "", Colour.CreationUser.First_Name & " " & Colour.CreationUser.Last_Name),
.CreationDate = Colour.CreationDate,
.CreationUserCode = Colour.CreationUserCode,
.LastUpdateDate = Colour.LastUpdateDate,
.LastUpdatedBy = If(Colour.LastUpdateUserCode Is Nothing, "", Colour.LastUpdateUser.First_Name & " " & Colour.LastUpdateUser.Last_Name),
.LastUpdateUserCode = Colour.LastUpdateUserCode,
.Colour_ID = Colour.Colour_ID,
.Colour_Name = Colour.Colour_Name}).OrderBy(Function(x) x.Colour_Name)
Return New ObservableCollection(Of FriendlyColours)(query)
End Using
我对上述问题,对于更复杂的连接实体,这种类型的查询需要太长时间。
我考虑过使用我的好友类来拉入相关数据,但是在断开的模式下,这对我不起作用。
显然,当断开连接,延迟加载是不是一个选项...
所以,我的问题是...是否有这样做的更好的办法?为了更好...阅读更快!
任何帮助将受到欢迎!也许我错过了一些明显的东西!
编辑...为了进一步解释:
- 我有一个返回所有的产品,以及他们 组件和产品库存产品查询...
- 有4个不同种类返回的组件列表,如 以及产品库存项目列表。
- 我拿出每套组件和产品库存项目,并填写一个 关联的网格与结果。
- 用户可以从各种组件或产品库存项目添加,编辑或删除项目。
查询结果(抱歉给的尺寸!
Dim query = (From ProductList In _DBContext.Products _
.Include(Function(x) x.CreationUser) _
.Include(Function(x) x.LastUpdateUser) _
.Include(Function(x) x.Colour) _
.Include(Function(x) x.License) _
.Include(Function(x) x.Pack_Size) _
.Include(Function(x) x.Customer) _
.Include(Function(x) x.Supplier) _
.Include(Function(x) x.ProductComponents) _
.Include(Function(x) x.ProductComponents.Select(Function(y) y.ApprovalType)) _
.Include(Function(x) x.ProductComponents.Select(Function(y) y.Component)) _
.Include(Function(x) x.ProductComponents.Select(Function(y) y.Component).Select(Function(z) z.ComponentType)) _
.Include(Function(x) x.Product_Stock_Item) _
.Include(Function(x) x.Product_Stock_Item.Select(Function(y) y.Pack_Type)) _
.Include(Function(x) x.Product_Stock_Item.Select(Function(y) y.Product_Sizing)) _
.Include(Function(x) x.Product_Stock_Item.Select(Function(y) y.Units_Of_Measure)) _
.Include(Function(x) x.ProductType) _
.Include(Function(x) x.ProductClassification) _
.Include(Function(x) x.ProductType.ProductDepts) _
.Include(Function(x) x.Season).AsNoTracking().OrderBy(Function(x) x.Product_Code).ToList
Select New FriendlyProducts With {.Colour_ID = ProductList.Colour_ID,
.Colour_Name = If(ProductList.Colour_ID Is Nothing, "", ProductList.Colour.Colour_Name),
.CreatedBy = If(ProductList.CreationUserCode Is Nothing, "", ProductList.CreationUser.First_Name & " " & ProductList.CreationUser.Last_Name),
.CreationDate = ProductList.CreationDate,
.CreationUserCode = ProductList.CreationUserCode,
.FriendlyCreationUser = ProductList.CreationUser,
.Cust_Product_Desc_24 = ProductList.Cust_Product_Desc_24,
.Cust_Product_Desc_48 = ProductList.Cust_Product_Desc_48,
.Customer_Code = ProductList.Customer_Code,
.Customer_Name = If(ProductList.Customer_Code Is Nothing, "", ProductList.Customer.NAME),
.Description = ProductList.Description,
.DesignNo = ProductList.DesignNo,
.Gender_ID = ProductList.Gender_ID,
.Gender_Name = If(ProductList.Gender_ID Is Nothing, "", ProductList.Gender.Gender_Name),
.LicenseCode = ProductList.LicenseCode,
.License_Name = If(ProductList.LicenseCode Is Nothing, "", ProductList.License.NAME),
.Pack_Size_ID = ProductList.Pack_Size_ID,
.Pack_Size_Name = If(ProductList.Pack_Size_ID Is Nothing, "", ProductList.Pack_Size.Pack_Size_Name),
.PackagingNR = ProductList.PackagingNR,
.ProductClassification_ID = ProductList.ProductClassification_ID,
.Product_Classification_Name = If(ProductList.ProductClassification_ID Is Nothing, "", ProductList.ProductClassification.ProductClassification_Name),
.Product_Code = ProductList.Product_Code,
.Product_Picture_Path = ProductList.Product_Picture_Path,
.ProductComponentsNR = ProductList.ProductComponentsNR,
.ProductType_ID = ProductList.ProductType_ID,
.ProductType_Name = If(ProductList.ProductType_ID Is Nothing, "", ProductList.ProductType.NAME),
.ProductDept_ID = If(ProductList.ProductType Is Nothing, Nothing, ProductList.ProductType.ProductDept),
.ProductDept_Name = If(ProductList.ProductType Is Nothing, "", (If(ProductList.ProductType.ProductDepts Is Nothing, "", ProductList.ProductType.ProductDepts.NAME))),
.SageDescription = ProductList.SageDescription,
.SeasonCode = ProductList.SeasonCode,
.Season_Name = If(ProductList.SeasonCode Is Nothing, "", ProductList.Season.NAME),
.StrikeOffNR = ProductList.StrikeOffNR,
.Supplier_Code = ProductList.Supplier_Code,
.Supplier_Name = If(ProductList.Supplier_Code Is Nothing, "", ProductList.Supplier.NAME),
.TransfersNR = ProductList.TransfersNR,
.Deleted = ProductList.Deleted,
.LastUpdateDate = ProductList.LastUpdateDate,
.LastUpdatedBy = If(ProductList.LastUpdateUserCode Is Nothing, "", ProductList.LastUpdateUser.First_Name & " " & ProductList.LastUpdateUser.Last_Name),
.LastUpdateUserCode = ProductList.LastUpdateUserCode,
.ProductComponents = If(ProductList.ProductComponents.Count > 0, GetProductComponentsByPrimaryName(ProductList.ProductComponents, "Component"), New ObservableCollection(Of FriendlyProductComponents)),
.ProductPackaging = If(ProductList.ProductComponents.Count > 0, GetProductComponentsByPrimaryName(ProductList.ProductComponents, "Packaging"), New ObservableCollection(Of FriendlyProductComponents)),
.ProductStrikeOffs = If(ProductList.ProductComponents.Count > 0, GetProductComponentsByPrimaryName(ProductList.ProductComponents, "Strike Off"), New ObservableCollection(Of FriendlyProductComponents)),
.ProductTransfers = If(ProductList.ProductComponents.Count > 0, GetProductComponentsByPrimaryName(ProductList.ProductComponents, "Transfers"), New ObservableCollection(Of FriendlyProductComponents)),
.ProductStockItems = If(ProductList.Product_Stock_Item.Count > 0, GetProductStockItems(ProductList.Product_Stock_Item), New ObservableCollection(Of FriendlyProductStockItems))
}).Where(Function(x) x.Deleted = False Or x.Deleted Is Nothing)
凡GetProductComponentsByPrimaryName
调用它简单地过滤按类型的组件,并返回一个友好的ObservableCollection的功能。
因此,每个相关的组件和产品库存项目集都作为ObservableCollection返回,我可以与之交互...
对不起,很长的文章!
编辑 - 13年8月3日:
我还没有解决这个问题上面,但我已成功地说服客户,他们不应该被检索所有结果,然后依靠用户以后过滤。
这也导致我重新调整我的过滤例程,以便在数据库上执行过滤,而不是在本地执行过滤。 这两个因素都意味着下面的查询现在以合理的速度运行。
我尝试手动填充我的实体,但是这花费的时间比Linq为我生成的查询要长得多。
其中一天,也许我会重温这个问题,看看我能学到什么。但现在,我已经回避了它!
@Trey ...非常感谢您的回复...我已经更新了我的OP,以提供更多细节....我不确定SP可以在这里工作...如果可以的话,我很想知道方法论! – PGallagher 2013-03-02 02:37:27
包括会杀了你。有一些是可以的,但是这么多只会杀死结果sql的性能。根据我的Twitter评论,我同意Trey。如果可能的话,你绝对应该考虑一个sproc。但问题是,谓词是动态的还是你总是在相同的字段上过滤? – 2013-03-02 03:28:47
啊,刚刚在我身上发现这必须是一个桌面应用程序而不是网络。想知道为什么是VB。大声笑。 – 2013-03-02 03:39:38