2016-11-18 6 views
0

私は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を取得したので、それが完全に適用されるかどうかはわかりません。

+0

私はAzure Mobileをよく知っていませんが、コンテキスト内で正しいEntry.Stateを持たないエンティティ、つまり接続されていないシナリオで発生する問題のように見えます。あなたのリンク先のあなたの問題を解決する最も投票された答えのようです。 'UpdateAsync'を実行する前に' aBooking.Hotel'ナビゲーションプロパティーの子をnullに設定し、 'HotelId'値だけを残してみてください。 – Diana

答えて

0

Azureモバイルアプリはリレーションシップをサポートしていません。あなたは、それに伴って起こる多くの問題の一つにぶつかっています。

オフライン同期を使用している場合、リンケージの必要性が低くなるようにテーブルを分解し、各テーブルを個別に同期します。

オフライン同期を使用していない場合は、カスタムAPIを使用して変更をデータベースにコミットします。

+0

本当ですか?私はこれが文書化されているところを見てみたいと思っています... – OffHeGoes

+0

[このマイクロソフトのブログでは、Mobileを使った1:nの関係についてのあなたの注意を喚起したいと思います。](https://blogs.msdn.microsoft.com/ azuremobile/2014/06/18/insertupdate-data-with-1n-relationship-net-backend-azure-mobile-services /を使用して)。 – OffHeGoes

+0

そのブログ記事は、Azure Mobile Appsの前身であるAzure Mobile Servicesに関する記事です。我々はAzure Mobile Appsでの関係をサポートしたことはありません。 –

関連する問題