我正在研究Azure移动应用程序并设置了测试服务和客户端。
我已设置以下实体服务端:
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; }
}
控制器:
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);
}
}
我使用CreateDatabaseIfNotExists<MobileServiceContext>
添加了一些默认数据,当我启动并测试Web API时,数据库会被填充,我很高兴能够正确设置密钥/关系。我只是使用Code First约定命名(根据this tutorial)
我还创建了一个包含以下实体的测试客户端:
public class Person
{
public string Id { get; set; }
public byte[] Version { get; set; }
public string Name { get; set; }
public virtual ICollection<Booking> Bookings { get; set; }
}
public class Booking
{
public string Id { get; set; }
public byte[] Version { get; set; }
public BookingStatus BookingStatus { get; set; }
public string PersonId { get; set; }
public string HotelId { get; set; }
public virtual Person Person { get; set; }
public virtual Hotel Hotel { get; set; }
}
public class Hotel
{
public string Id { get; set; }
public byte[] Version { get; set; }
public string Title { get; set; }
public virtual ICollection<Booking> Bookings { get; set; }
}
使用此测试逻辑:
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
失败了:
由于冲突导致操作失败:&#39;违反PRIMARY KEY约束&#39; PK_dbo.Hotels&#39;。无法在对象&#39; dbo.Hotels&#39;中插入重复的密钥。重复键值为(0e6e1bae-bd59-46ac-9630-a2b53dd04a90)。\ r \ n语句已终止。
但是为什么要再次插入我的孩子对象?首先,我没有改变它,其次,它有一个Id
,{{1等等。
我找不到任何有关Azure移动应用程序的类似问题,但我确实找到了this SO Post regarding Entity Framework但是OP谈到了手动创建子项,因此我不确定它是否完全适用,因为我从中获取了子实体数据库通过CreatedAt
。
答案 0 :(得分:0)
Azure移动应用不支持关系。你正在碰到与之相关的众多问题之一。
如果您正在使用离线同步,那么请对表进行分解,以便不再需要链接,然后单独同步每个表。
如果您没有使用离线同步,请使用自定义API将更改提交到数据库。