Entity Framework 5 Database First、VB.net、Linq、SQL Server 2008 R2、および切断されたリポジトリ パターンを利用するアプリケーションがあります。
EF5.x dbContext ジェネレーターを使用して POCO を作成し、T4 テンプレートを変更して、INotifiyPropertyChanged イベントの発生など、さまざまな追加のビットとボブを追加しました。
さまざまなリンク テーブルがあり、データを「わかりやすい」方法で表示する必要があります。
例として、次の 2 つのテーブルがあります。
色:
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)
WhereGetProductComponentsByPrimaryName
は、単純にコンポーネントをタイプでフィルタリングし、Friendly ObservableCollection を返す関数を呼び出します。
したがって、関連する各コンポーネント セットと製品ストック アイテムは ObservableCollection として返され、これを操作できます...
長文すみません!
編集 - 08-03-13:
上記の問題は解決していませんが、クライアントに、すべての結果を取得してから、後でフィルタリングするためにユーザーに依存するべきではないことを納得させることができました。
これにより、フィルタリングがローカルではなくデータベースで実行されるように、フィルタリングルーチンを再調整することにもなりました。これら 2 つの要因は両方とも、以下のクエリが適切な速度で機能するようになったことを意味します。
エンティティを手動で入力しようとしましたが、Linq が生成したクエリよりもはるかに時間がかかりました。
近いうちに、この問題を再検討して、何を学べるか見てみようと思います。でも、とりあえず回避しました!