1

保存しようとしているエンティティのクライアント側グラフがあります。エンティティ (後述) を追加しようとすると、Breeze はタイトルのエラーを報告します。

必要に応じてエンティティを除外/含めることができるため、Breeze がグラフ内の他のすべてを保持し、最後にこのエンティティを追加しようとすることができました。エラーは一貫して報告されます。

コントローラーの saveBundle でエンティティーの JSON 表現をキャプチャーし、それをデータベースに手動で挿入できるため、エンティティーが正しく作成されていることが保証されます。

私はそれをさらにデバッグする方法について行き詰まっており、いくつかのガイダンスをいただければ幸いです。

コード ファースト クラスは次のとおりです (必須: DateTime、value、Message、User):

public Guid ID { get; set; }

public Guid MessageID { get; set; }
public Guid UserID { get; set; }

public DateTime DateTime { get; private set; }
public float Value { get; set; }

public virtual Message Message { get; set; }
public virtual User User { get; set; }

public virtual ICollection<PropertyValue> PropertyValues { get; set; }

保存バンドルは次のとおりです。

{
  "entities": [
    {
      "ID": "cdc7a329-1ddc-4535-98f1-fd878af48823",
      "MessageID": "57e88bc1-edc2-4905-af74-09df83edeba5",
      "UserID": "1269a0ad-1019-471c-bdf9-a6e61aea468c",
      "DateTime": "2013-01-04T23:32:01.067Z",
      "Value": 0,
      "entityAspect": {
        "entityTypeName": "Score:#MyProjectName.Repo",
        "entityState": "Added",
        "originalValuesMap": {},
        "autoGeneratedKey": {
          "propertyName": "ID",
          "autoGeneratedKeyType": "Identity"
        }
      }
    }
  ],
  "saveOptions": {
    "allowConcurrentSaves": false
  }
}

SQLは次のとおりです。

insert into Scores (
    [MessageID],
    [UserID],
    [DateTime],
    [Value]
) values (
    '57e88bc1-edc2-4905-af74-09df83edeba5',
    '1269a0ad-1019-471c-bdf9-a6e61aea468c',
    '2013-01-04T23:28:18.872Z',
    0
)

アップデート

サーバーのイベントのバージョンは、「System.ArgumentNullException」で始まります

Value cannot be null.\r\nParameter name: source

と:

at System.Linq.Enumerable.Select[TSource,TResult](IEnumerable`1 source, Func`2 selector)
at Breeze.WebApi.EFContextProvider`1.SaveChangesCore(Dictionary`2 saveMap)
at Breeze.WebApi.ContextProvider.SaveChanges(JObject saveBundle)
at [MyProject].[MyController].SaveChanges(JObject saveBundle) in ..\Controllers\[MyController].cs:line 53
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass13.<GetExecutor>b__c(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.<>c__DisplayClass5.<ExecuteAsync>b__4()
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)
4

2 に答える 2

3

更新された質問のスタック トレースは、サーバーで例外が発生したことを確認していると思います。

のソースを見ると、報告している例外は、EF 検証エラーを処理する内でEFContextProviderスローされているようです(~ 125 行目)。EF からのエンティティ検証エラーに関するメッセージを準備していますが、誤ったエンティティのキ​​ーがないため (予期せず) 失敗します。ありえないはずです(笑)!EF はキーなしでエンティティを保存するように求められたようです。EFContextProvider.SaveChangesCoreforeachsaveChangesEntityKeyValues

次のように診断に役立てることができます。

  1. EFContextProvider2モデル プロジェクトに新しいクラスを作成する
  2. EFContextProvider GitHub ソースからのコピーを貼り付けます。
  3. 必ずクラスの名前を変更しEFContextProvider2、プロジェクトをコンパイルしてください
  4. EFContextProvider2Web API コントローラーで置き換えます
  5. キーをフォーマットする直前に、124 行目にブレークポイントを設定します。
  6. デバッガーで問題を再現

を調べますkey.EntityKeyValues。問題のあるエンティティの場合、それらは null であるに違いありません。それは何の実体ですか?エラーの内容はeve.ValidationErrors? この特定のエンティティはモデルでどのように定義されていますか?

エラーに関する詳細情報があれば、私たち (まあ、あなた) もより多くのことを知ることができます。

発見したことをお知らせください。

1月9日更新

コードを少し見たので、問題はより明白になりました。

サーバー側モデルは、Score.Message および Score.User プロパティが必要であると述べています。サーバーのEFコンテキストには存在しないため、検証に失敗しています。

Score.Message と Score.User は、関連する Message オブジェクトと User オブジェクトをそれぞれ返すナビゲーション プロパティです。

保存すると、EF はこれらの関連エンティティが存在することを忠実に検証します。そうではありません。それらは、(正しく) 遅延読み込みをオフにしたためではありません。これは、EF がそれらを取得できないことを意味します。

これらのエンティティが Breeze クライアントのキャッシュにあるかどうかはまったく問題ではありません。Breeze はそれらを保存バンドルの一部としてサーバーに送信しません。

そうすべきでもありません!新しいスコアを保存しています。ただし、スコアに関連するメッセージまたはユーザーは変更していません。したがって、保存が必要な唯一のエンティティはスコアです。これが、保存バンドル内で唯一のエンティティである理由です。

EF は、あなたが指示したことを正確に実行しています。関連するメッセージまたはユーザーが存在しない場合は悲鳴を上げます。

あなたへの私の質問は、なぜメッセージまたはユーザーが必要なのですか? スコアには外部キーがあります。それらのキーが有効であることを確認しようとしていますか? データベース内の実際の Message および User 行を参照していることは? 私にはやり過ぎのように思えます。参照制約がオンになっている場合、データベースはそれを保証します。これらの制約がオフの場合、スコアの挿入/更新中にこれらの検証によって保護されます。しかし、誰かがメッセージまたはユーザーを個別に削除するのを止めることはできません...したがって、スコアを孤立させます。

主張する場合は、BeforeSave... メソッドでこれらのプロパティを明示的に LOADING することで、EF を満たすことができます。私はあなたがそれを行うためのEFチョップを持っていると仮定します...そうでなければ、オンラインでそれを見つけることができます.

しかし、私が言ったように、これは私にはやり過ぎのように思えます。

ところで、Score の Message および User プロパティの [Required] 属性をコメントアウトすると、EF は新しい Score を保存できるようになりました。アプリは他の理由でクライアントに戻ってきました(console.debug私の環境では定義されていませんでした)が、それはあなたに任せます。

あなたのモデル

どうやってこのモデルを手に入れたのですか?スコアは何かから生成されたようです。私は MVC のスキャフォールディングに詳しくないので、私の無知を許してください。しかし、私はそれを見ると醜いことを知っています.2つの部分クラスのビジネスは、そのうちの1つがメタデータの「相棒」クラスを保持しています...今は醜いです。そして、属性の多く (ほとんどではないにしても) は不要です。

私はそのすべての粗雑さの正当な理由を考えることはできません. 適切なプロパティの検証属性で飾られた単一の単純な POCO っぽいクラスの何が問題なのですか。これを行うと、モデルがはるかに理解しやすくなります。

jQuery が延期された理由は何ですか?

トピックから外れていることは承知していますが、Q promiseを jQuery deferred に変えるために多大な努力を払っているようですね? それはあなたの選択です。しかし、deferred でできることで、Q と同じかそれ以上にできることはありません。Q に固執すれば、多くの醜いコードを切り取ることができます。

于 2013-01-05T19:48:00.770 に答える
0

私はここで完全にずれているかもしれませんが、それは DateTime フィールドだと思います。フィールドをnull許容値に変更してみてください。

  public DateTime? DateTime { get; private set; }

EF の内部のどこかで、「2013-01-04T23:32:01.067Z」が有効な形式として認識されないため、無効になります。SQL はそれを認識するので、insert ステートメントは機能します。

「1/4/2012 23:32:01」などのように送信されるように、moment.js を使用して日付をフォーマットすることで、この問題を回避しました。

ご存知かと思いますが、Z は UTC になります。日付が 8 時間進んでいるという問題がありました (私は CA にいます)。それをテキストのような形式にフォーマットすることもそれを処理しました。

于 2013-01-06T02:03:48.283 に答える