首页 > 解决方案 > Azure 移动应用和 Xamarin 尝试将 1:1 相关实体插入数据库

问题描述

我有两个对象 GiftBasket 和 Gift

礼品篮.cs

public class GiftBasket:EntityData
{
    public string MerchantId { get; set; }
    public string UserId { get; set; }
    public string Source { get; set; }
    public bool IsRedeemed { get; set; }

    public Gift Gift { get; set; }
}

礼物.cs

public class Gift: EntityData
{
    public int Value { get; set; }
    public string Type { get; set; }
}

我正在尝试将新的 GiftBasket 插入数据库

我的客户端代码

管理器.cs

public async Task InsertGiftBasketAsync(GiftBasket giftBasket)
        {
            try
            {
                await giftBasketTable.InsertAsync(giftBasket);
            }
            catch (MobileServiceInvalidOperationException msioe)
            {
                Debug.WriteLine("Invalid sync operation: {0}", new[] { msioe.Message });

            }
            catch (Exception e)
            {
                Debug.WriteLine("Sync error: {0}", new[] { e.Message });
            }
        }

我的页面内的代码:

GiftBasket giftBasket = new GiftBasket
{
Id = Guid.NewGuid().ToString(),
MerchantId = Wallet.MerchantId,
UserId = Wallet.UserId,
Gift = Gifts.ElementAt(2).Gift,
Source = "Scratch",
IsRedeemed = false
};
await manager.InsertGiftBasketAsync(giftBasket);

当我使用我的移动应用程序尝试此操作时,我收到此错误:

[0:] Invalid sync operation: The request could not be completed.  (Internal Server Error)

当我尝试使用 Postman 手动添加新对象时,出现此错误:

"message": "The operation failed with the following error: 'Cannot insert the value NULL into column 'Gift_Id', table 'nojoom_db.dbo.GiftBaskets'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated.'."

我究竟做错了什么 ?如果我编辑了我的 GiftBasket 模型并删除了与 Gift 的关系并使它像这样

public string Gift_Id { get; set; }

插入工作正常,但我牺牲了在一次 API 调用中获取相关数据作为礼物。

请注意,GiftBasket 是数据库的一个新条目,但其中的 Gift 已经在 Gift table 的数据库中,我不想同时插入新的。

更新

我将模型更改为:

 public class GiftBasket:EntityData
    {
        public string MerchantId { get; set; }
        public string UserId { get; set; }
        public string Source { get; set; }
        public bool IsRedeemed { get; set; }

        public string GiftId { get; set; }
        public virtual Gift Gift { get; set; }

    }

  public class Gift: EntityData
    {
        public Gift()
        {
            GiftBaskets = new List<GiftBasket>();

        }
        public int Value { get; set; }
        public string Type { get; set; }

        public virtual ICollection<GiftBasket> GiftBaskets { get; set; }

    }

这意味着我实现了一对多关系,这是有道理的,因为一个礼品篮有很多礼物。

但是如果我想要一对一的关系呢?这是如何实现的?

 public class GiftBasket:EntityData
    {
        public string MerchantId { get; set; }
        public string UserId { get; set; }
        public string Source { get; set; }
        public bool IsRedeemed { get; set; }

        public string GiftId { get; set; }
        public virtual Gift Gift { get; set; }

    }

 public class Gift: EntityData
        {

            public int Value { get; set; }
            public string Type { get; set; }

            public virtual GiftBasket GiftBasket { get; set; }

        }

当我这样做时,我在调用 GET 后收到此错误

"Unable to determine the principal end of an association between the types '****.DataObjects.GiftBasket' and '****.DataObjects.Gift'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations."

当我添加[ForeignKey("GiftId")]礼品篮时,我收到此错误

"The property 'GiftId' cannot be configured as a navigation property. The property must be a valid entity type and the property should have a non-abstract getter and setter. For collection properties the type must implement ICollection<T> where T is a valid entity type."

标签: entity-frameworkxamarin.formsazure-mobile-services

解决方案


Azure 移动应用假定每个表都是独立的。它不处理连接。

您可以自己在客户端进行连接,或者对离线表使用 LINQ,或者通过您创建的 SQLiteStore 对象使用直接 SQLite 命令。

另一种方法是“展平”客户端上的对象模型(这 - 因为它是 1:1,所以应该不是问题),所以你只有一个 GiftBasket(没有礼物),然后你将请求分开服务端(提交请求时更新两个 EF 模型,或在查询中组合两个 EF 模型)。


推荐阅读