私はAzure Mobile Appを見ており、テストサービスとクライアントをセットアップしています。
私はセットアップ次のエンティティのサービス側ました:私はCreateDatabaseIfNotExists<MobileServiceContext>
を使用して、いくつかのデフォルトのデータを追加した
public class BookingController : TableController<Booking>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
MobileServiceContext context = new MobileServiceContext();
DomainManager = new EntityDomainManager<Booking>(context, Request);
}
// GET tables/Booking/48D68C86-6EA6-4C25-AA33-223FC9A27959
public SingleResult<Booking> GetBooking(string id)
{
return Lookup(id);
}
// GET tables/Booking
public IQueryable<Booking> GetAllBookings()
{
return Query();
}
// PATCH tables/Booking/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task<Booking> PatchBooking(string id, Delta<Booking> patch)
{
return UpdateAsync(id, patch);
}
}
と私は、Web APIを起動してテストします。
public class Hotel : EntityData
{
public string Title { get; set; }
public virtual ICollection<Booking> Bookings { get; set; }
}
public class Booking : EntityData
{
public BookingStatus BookingStatus { get; set; }
[ForeignKey("PersonId")]
public virtual Person Person { get; set; }
[ForeignKey("HotelId")]
public virtual Hotel Hotel { get; set; }
public string PersonId { get; set; }
public string HotelId { get; set; }
}
public class Person : EntityData
{
public string Name { get; set; }
public virtual ICollection<Booking> Bookings { get; set; }
}
とコントローラをDBが作成され、キー/リレーションシップが正しく設定されていることがうれしく思います。私はちょうど私がまた次のエンティティでテストクライアントを作成しました(this tutorialあたりとして)
命名コードファースト規約を使用しています:
そして、このテスト・ロジックを持つ:
using (var client = new MobileServiceClient(m_Url, new ODataParameterHandler())
{
client.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
client.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
var bookingTable = client.GetTable<Booking>();
var bookings = await placementTable
.Where(p => p.BookingStatus == BookingStatus.Confirmed && p.PersonId == 10)
.WithParameters(new Dictionary<string, string> { { "expand", "Hotel" } })
.ToListAsync();
var aBooking = bookings[0];
aBooking.BookingStatus = BookingStatus.Cancelled;
await bookingTable.UpdateAsync(aBooking);
}
// Class to allow $expand= querystring value to be passed in.
public class ODataParameterHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
UriBuilder builder = new UriBuilder(request.RequestUri);
builder.Query = builder.Query
.Replace("expand", "$expand")
.TrimStart('?');
request.RequestUri = builder.Uri;
return await base.SendAsync(request, cancellationToken);
}
}
GET/ToListAsync
は正常に動作し、子Hotel
オブジェクトが私のBooking
に接続されています。しかし、Update
はで失敗します。
操作が原因の競合に失敗しました:PK_dbo.Hotels「PRIMARY KEY制約の違反 『』。オブジェクト 'dbo.Hotels'に重複キーを挿入できません。重複するキー値は(0e6e1bae-bd59-46ac-9630-a2b53dd04a90)です。\ r \ nステートメントが終了しました。
なぜ、私の子オブジェクトを再度INSERTしようとしていますか?私はAzureのモバイルアプリに関するいかなる同様の問題を見つけることができませんが、私はthis SO Post regarding Entity Frameworkを見つけましたが、手動で作成した程度OP会談など
を第一に、私はそれを変更していない、そして第二に、それはId
を持って、CreatedAt
子供のため、TableController
を介してDBから子Entityを取得したので、それが完全に適用されるかどうかはわかりません。
私はAzure Mobileをよく知っていませんが、コンテキスト内で正しいEntry.Stateを持たないエンティティ、つまり接続されていないシナリオで発生する問題のように見えます。あなたのリンク先のあなたの問題を解決する最も投票された答えのようです。 'UpdateAsync'を実行する前に' aBooking.Hotel'ナビゲーションプロパティーの子をnullに設定し、 'HotelId'値だけを残してみてください。 – Diana