問題タブ [graphdiff]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
entity-framework - 式ツリーの例外
これは私のモデルです:
Business
これで、すべてのプロパティとコレクションが適切に設定された単一のエンティティとして、一連のデータ全体で構成されるフォームを受け入れるコントローラー アクションができました。
ここで、すべてのプロパティとコレクションを再帰的に調べて、データベース グラフと比較する必要があります。それらが存在しない場合は追加し、すべてのプロパティを再度調べて、ナビゲーション プロパティがなくなるまで同じことをより深いレベルで実行します。前の例で述べたよりも多くのプロパティと子孫があるので、それらを手動で見ていくだけです。
この回答のおかげで、状況に対する素晴らしい解決策を提供する GraphDiff を見つけました。
私が呼び出している更新クエリは次のとおりです。
次の例外がスローされます。
System.InvalidCastException: タイプ 'System.Linq.Expressions.MethodCallExpressionN' のオブジェクトをタイプ 'System.Linq.Expressions.MemberExpression' にキャストできません。
ソース コードのデバッグを試みましたが、私は式ツリーの専門家ではありません。内部Include
呼び出し (ストア オブジェクトをロードするためのオブジェクト グラフを含めるため) がアタッチしようとすると、問題が発生しWorkingPeriods
ます。再帰。少しいじりましたが、式ツリーに関する幅広い知識を持っている人なら、これを簡単に解決できると確信しています。その上で何か提案をいただければ幸いです。
インクルード パス式は次のように生成されるはずです。
基本的に、再帰呼び出しは内部インクルードをメソッド呼び出しとして返し、それを処理せずに、公開することを意図したコレクション プロパティを返すため、例外がスローされます。
entity-framework-6 - 切断された子エンティティを持つ切断された複雑なグラフ
コレクションの子エンティティを含む複雑なグラフがあります。親エンティティと子エンティティの関係は 1 対多の関係であり、独立した関連付けがあります。避けたい手動同期なしではグラフを永続化できないことはわかっています。GraphDiffソリューションが有望であることがわかり、調査を開始しましたが、シナリオがやや特殊であるため、意図したことを達成できませんでした。この問題は純粋に GraphDiff に関連していますが、他の解決策も歓迎します。
私の Person.Cars コレクションには常に 1. 新しい車のオブジェクトがあります。2. 値が更新された既存の自動車オブジェクト (保険またはサービスの日付)。
Person の Id プロパティと Car の PersonId は 0 になります。
この時点では、受け取ったオブジェクトを追加または更新する必要があるかどうかはわかりません。子エンティティ (車) の PersonId も 0.Now になります。
これを克服するには、個人の Id プロパティを更新する必要があります。
dbPerson.Cars 内のすべてのエンティティを削除し、_person.Cars を dbPerson.Cars に追加して保存します。これは、データベースの Cars テーブルのすべてのレコードが削除され、_person.Cars のレコードが挿入されることを意味します。子エンティティに Id プロパティがないため、これが発生していることに気付きました。手動で設定する必要があります。
今電話したら
これにより、永続オブジェクトで欠落している一時オブジェクトからコレクションにエンティティが追加され、永続オブジェクトで一致するオブジェクトが更新され、残りのエンティティが永続オブジェクトから削除されます。
dbCars.Count が 8 で、_person.Cars.Count が 3 であるとします (値が更新された新しい車 1 台と古い車 2 台)。
dbCars で一致する _person.Cars の 2 つの古い車が更新されます。dbCars で一致しない _person.Cars から 1 台の新しい車が追加されます。
新しい車を追加したので、dbCars の数は 9 になるはずです。カウントを確認します。
dbCarCount は 3 になります。dbCars の残りの 6 台の車は削除されます。
私はあなたのソリューションを使用したいので、私が間違っていることを願っています.この分野での私の仕事は行き詰まっています. 何か不足している場合や、さらに情報が必要な場合はお知らせください。私はすべてのテスト経験を GraphDiff に当てはめようとしたので、私の記事が混乱を招くことは承知しています。この問題に対処していただければ幸いです。
c# - GraphDiff で式ツリーを更新する方法
私が扱っているオブジェクトグラフは基本的に次のとおりです。
既存の Technology、SkillCategory、SkillCompetency の組み合わせを選択することで、新しいスキルをユーザーに追加できます。GraphDiff を使用して、EF が重複した Technology、SkillCategory、SkillCompetency レコードを追加しようとするのを防止しようとしました (そして失敗しました!)。これは、GraphDiff を使用して達成するのは簡単なはずですが、GraphDiff を見つけるだけで EF カップルに比較的慣れていないため、苦労しています。
何か案は?
graphdiff - GraphDiff はデータベース ファーストのシナリオで機能しますか?
既存の SQL Server db を持つアプリケーションで Entity Framework を使用しています。POCO Entity Generator を使用すると仮定して、GraphDiff をデータベース ファーストのシナリオで使用できますか?
c# - GraphDiff を使用して多対多の関連付けを更新する
次のデータモデルがあります。
私のビジネス ロジックは切り離されたエンティティで動作するため、GraphDiff を使用して更新を実行しています。PerfModes/CalcPoints の関連付けを更新できません。概念的には、Block は CalcPoints と PerfModes を所有していますが、CalcPoints は任意の数の PerfModes に関連付けることができます。
ブロックレベルで更新しようとしています。私が思いついたコードはエラーをスローしませんが (他の試行ではエラーが発生しました)、PerfModes/CalcPoints の関連付けも更新しません。
私はおそらく EF グラフと GraphDiff を完全には理解していません。多対多の PerfModes/CalcPoints の関連付けが正しく更新されるようにするにはどうすればよいですか?
編集
andyp の回答を確認した後、GitHub から最新バージョンの GraphDiff を取得し、次のマッピングを試しました。
これにより、PerfModes/CalcPoints の関連付けが正しく更新されます。元のマッピングに戻しましたが、関連付けが更新されないという問題がまだ見られたので、モデル全体を一度に更新しようとすると問題があるようです。複数の UpdateGraph 呼び出しを行っても問題ありませんが、それらを分割するにはどうすればよいでしょうか?
関連するコードと失敗した単体テストの要点を次に示します。
EF で生成されたコンテナー クラスを継承して、プロキシの作成を無効にして独自のコンテキストを作成しています。それはGraphDiffに問題を引き起こしますか?
c# - 切断された環境 (EF) でデータベースによって生成された ID でエンティティ グラフ ID を更新します。
私はプロジェクトEF6 code first
で働いています。WinForm
からエンティティを読み取りDb
、更新してから に保存するために、次の方法を使用しましたDb
。
- を使用してエンティティグラフを読み取る ( disposes
Linq to entities
を読み取った後)DbContext
- 読み取っ
Entity
たグラフをエンド ユーザーに表示します。 - エンド ユーザーは、この変更を
Entity
グラフ に適用できます。- ルート エンティティの更新
- いくつかの子エンティティを追加
- 一部の子エンティティを編集する
- いくつかの子エンティティを削除します
- ユーザーがメソッドを呼び出して変更を永続化する
Db
- 新しい
DbContext
インスタンスを作成します。 Entity
同じのグラフをリロードしますDb
- を使用して、すべてのプロパティの値をユーザー エンティティからリロードされたエンティティにマップします。
AutoMapper
- 6 ステップの結果エンティティを my
DbContext
usingに添付しますGraphDiff
/li>DbContext.SaveChanges();
への変更を保持するための呼び出しDb
それはうまく動作します、
2 番目のグラフでは、ユーザーによって追加された Child13 と Child22 が呼び出され、uow.SaveChanges()
それらが保存されDb
、そのId
s が割り当てられます。しかしChild13.Id
、オブジェクトではChild22.Id
まだ、手動でs を更新できますが、生成された s でこれらの値を更新する一般的な方法を探しています。entity
0
Id
Id
Db
Id
web-services - サービス指向の親子トランザクションをどのように実行しますか?
例:
SalesOrder は、SalesOrderHeader と 1 つ以上の SalesOrderItems で構成されます。既存の SalesOrder を編集する場合、SalesOrderHeader を変更でき、SalesOrderItems を追加、変更、および削除できます。すべての変更は、単一のトランザクションで保存する必要があります。複数のユーザーが、オプティミスティック コンカレンシーで同時に SalesOrder を編集できます。
保存を 1 回のトランザクションで行うという要件により、SaleOrderHeader と SalesOrderItems の両方を 1 回のサービス呼び出しで通信することが推奨されると思います。子データをその親と一緒にパッケージ化するということは、子データが追加、変更、または削除されるかどうかについてある程度理解する必要があるということです。
子エンティティの変更追跡は、サーバーまたはクライアントで発生する可能性があります。
サーバーでの変更追跡
この戦略の考え方は、どの SalesOrderItem が追加、変更、または削除されたかを追跡することなく、クライアントが意のままに SalesOrder を変更できるということです。SalesOrderItems の状態は、保存サービスが呼び出されたときにサーバー上で決定されます。
サーバーは、サービス呼び出し間でステートレスのままにする必要があります。これは、SalesOrder を取得してから最終的に保存するまでの間、サーバーが SalesOrder の状態に関する情報を保持できないことを意味します。変更されたオブジェクト グラフをデータベース オブジェクト グラフと比較することによって、サーバーがそのエンティティの状態を判断する場合に残された唯一のオプションです。
nHibernate には、これを実現するためのマージ機能があります。エンティティ フレームワークでは、これを追加する機能リクエストが最も多く投票されました。GraphDiffと呼ばれる EF 用のオープン ソース実装もあります。
サービスの設計と使用が非常に簡単になるため、これは理論的には素晴らしいことのように思えます。ただし、この戦略には 2 つの大きな問題があると思います。1つ目はパフォーマンスです。保存するたびに、オブジェクト グラフ全体を送り返す必要があります。SalesOrderItem が変更されたかどうかにかかわらず、返送する必要があります。そうしないと、サーバーは削除されたと見なします。2 番目の問題はさらに重大で、並行性に関係しています。ユーザー 1 が SalesOrderItem を SalesOrder に追加し、ユーザー 2 が同じ SalesOrder に変更を加えた場合、ユーザー 2 が保存すると、サーバーは、ユーザー 1 によって追加された SalesOrderItem がユーザー 2 のオブジェクト グラフに含まれていなかったため、削除する必要があると想定します。サーバー側の変更追跡の実装でこれを防ぐ方法がわかりません。
クライアントでの変更追跡
もう 1 つの方法は、クライアントにエンティティの変更を追跡させ、保存サービスを呼び出すときにその状態を伝えることです。利点の 1 つは、クライアントが変更されていない子エンティティを送信する必要がないことです。これはパフォーマンスに役立ちます。欠点は、追加、変更、または削除されたかどうかを追跡するために、すべてのエンティティに「ObjectState」の行に沿って何かという名前の追加のプロパティが必要になることです。これにより、サーバー上のエンティティ モデルが非常に煩雑になり、ビジネス ドメインとは関係のない問題でいっぱいになります。これはまた、サービスのさまざまなコンシューマーにこの状態を維持する責任を負わせます。もう 1 つの問題は、削除されたエンティティの処理が困難になることです。SalesOrderHeader は、削除された SalesOrderItems のリストを維持する必要がありますか? または、SalesOrderItems に削除済みの状態を割り当てて、クライアント UI で除外する必要がありますか?
ブリーズJavaScript ライブラリにはクライアント側のエンティティ追跡の独自の実装があることは知っていますが、その実装にはクライアント側とサーバー側の両方のコンポーネントが必要であることが懸念されます。サービスレイヤーは、どちらの側で使用するテクノロジーを分離すべきではないでしょうか? 非 JavaScript クライアントが私のサービスを使用したい場合はどうすればよいですか?
質問
これは、大部分のサービス実装で対処する必要がある一般的なシナリオだと思います。私は何か間違った仮定をしたことがありますか、それとも私は何か異常または普通のことをしていますか? どのような戦略を実行しましたか? 合理的な代替手段はありますか?
c# - GraphDiff がオブジェクト グラフで欠落している子を削除しないようにするにはどうすればよいですか?
私は現在、ある時点でオブジェクトと関連する子の正確な状態を取得できるようにする必要があるプロジェクトに取り組んでいます。これを行うために、次のようなモデルを考え出しました。
オブジェクトがあるとしましょう:
これにより、期待どおり GraphDiff で保存されます。その後、親 1v1 をロードし、何かを変更します。バージョンは 2 に上がり、子オブジェクトのバージョンも 2 に上がります。このオブジェクトは次のようになります。
また、必要に応じて保存します。これらのオブジェクトごとに新しいレコードが挿入され、古いバージョンが残ります。ただし、子 1 オブジェクトのみを変更すると、上記のモデルから次のようになります。
GraphDiff を使用して保存すると、Child 1v2 がグラフに存在しないことがわかり、データベースから削除されます。これを回避する唯一の方法は、2 つの get メソッドを使用することです。実際に使用可能なもの、最大バージョンの親と子をロードするもの、およびすべての履歴オブジェクトを含むグラフ全体をロードするものです。
私はそれをしないほうがいいです。新しい GraphDiff 機能を発表するこのブログ投稿は、いくつかの監査機能が利用できる可能性があることを示しているようですが、これを使用する方法に関するドキュメントは見つかりません。
追加/更新のみのモードで GraphDiff を使用する方法はありますか?
c# - 1 対 1 の関係でグラフを更新する
VoceRicevuta のコレクションを保持するクラス Ricevuta があります。
VoceRicevuta は、さまざまなクラスへのオプションの参照を保持します。Prestazione クラスへの参照のみを考えてみましょう。
さて、問題は次のとおりです。Prestazione のインスタンス (PreInst と呼びましょう) を作成し、データベースに保存します。その DbContext インスタンスから PreInst を切り離します。次に、PreInst を別のフォーム (別の DbContext - 私はそれを行う必要があります) に渡し、Ricevuta、VoceRicevuta (作成したばかりの Ricevuta に追加) を作成し、PreInst を VoceRicevuta Prestazione プロパティに割り当てます。また、PreInst にもいくつか変更を加えました。ここで、新しいRicevuta、新しいVoceRicevuta、そのPreInstとの関係、およびPreInstへの変更をデータベースに保存したいと思います。私は以下を実行します:
しかし、私はエラーが発生します:
「PRIMARY KEY 制約 'PK_dbo.Prestazioni' に違反しています。オブジェクト 'dbo.Prestazioni' に重複キーを挿入できません。重複キーの値: (12115)」
理由がわかりません!グラフの一部が既に Db に存在し、その結果として動作する場合、Graph diff の目的はチェックしていませんか?
上記のコードを実行して保存する前に、PreInst を DbContext にアタッチしようとしました。スローされるエラーは次のとおりです。
ヒントはありますか?