为什么Azure移动应用程序的数据模型中有一个字符串ID?

10

我正在学习使用Azure移动应用程序中的C#编程。我创建了一个Model来连接我的Azure SQL数据库,创建了一个DataObject,如下所示:

public class Account : EntityData
{
    //public int id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PhoneNumber { get; set; }
    public string Password { get; set; }
    public DateTime dtCreated { get; set; }
    public Guid oGuid { get; set; }

}

请注意,我在上面注释了public int id;这是因为查询时它会导致重复列错误。

最后,我使用新创建的 Account DataObject 创建了一个控制器。

所以我运行了应用程序并点击"tables/Account"函数,但它返回零行 (但有数据,我可以用在 Azure 移动应用中使用的用户进行查询)。

然后我注意到模型架构如下:

[
  {
    "id": 0,
    "FirstName": "string",
    "LastName": "string",
    "PhoneNumber": "string",
    "Password": "string",
    "dtCreated": "2016-07-06T17:45:47.114Z",
    "oGuid": "string",
    "Id": "string",
    "Version": "string",
    "CreatedAt": "2016-07-06T17:45:47.114Z",
    "UpdatedAt": "2016-07-06T17:45:47.114Z",
    "Deleted": true
  }
]

我看到配置的模型有几个问题(而且我不知道某些列来自哪里...)

首先,id被列两次,一次为int(必须是我的),另一个id为字符串,我不知道它来自哪里。

此外,在数据库中,oGuid的类型为uniqueIdentifier,而不是字符串。这可能是个问题,也可能不是,因为我还无法测试。

然后就是其他在我的数据库中不存在的列,包括CreatedAt(datetime)、UpdatedAt(datetime)、Version(string)和Deleted(bit)。

我认为我没有从那个调用中得到任何数据的原因/问题是数据不匹配。

我需要在api测试中添加在模型中列出的其他列吗?

我还尝试过调用/table/Account/3以加载特定的帐户,但没有返回任何行...我猜这是模型不匹配,但我不确定是不是这个问题或其他问题导致的?我没有看到任何错误或警告。


更新

我弄清楚了模型先和Azure之间发生了什么以及如何将现有的DB附加到新代码中。我要在这里发布这篇文章希望能为其他人节省时间。这应该更容易做到。我不喜欢CodeFirst(但),因为我喜欢手动控制DB...所以这使得我更容易处理db后端。

首先,我创建了一个新项目(Azure移动应用程序),然后在模型下右键单击模型并添加->新实体数据模型,然后添加Azure数据库名称、密码,并使用下面使用的"用户创建的配置文件名"。此连接必须在web.config中进行编辑,如下所示。

然后,我必须为DataObjects中的表创建模型(不包括MS所需的列),并从dataobject创建控制器。然后,我需要编辑web.config并设置非实体DB连接字符串:例如:

<add name="[user created preset name]" providerName="System.Data.SqlClient" connectionString="Server=[Azuredb server connection];initial catalog=[DBName];persist security info=True;user id=[user];password=[pass];MultipleActiveResultSets=True"/>

最后,在MobileServiceContext中,我需要将DataObject模型映射到Azure SQL表格,并将连接字符串从默认的MS_TableConnectionString设置为web.config中的连接字符串。

    private const string connectionStringName = "Name=[user created preset name]";

在 OnModelCreating() 中,我添加了以下内容:

    modelBuilder.Entity<Account>().ToTable("tblAccount");

Account是我在DataObjects中创建的模型(类),tblAccount是AzureDB中的表名。


1
在与此相关的工作中,另一个评论是:ID列应该是“uniqueidentifier”类型,而不是字符串。 - Zonus
1个回答

6
实体数据(EntityData)抽象类包含额外的字段——对于移动离线同步,有五个字段:
  • Id(字符串——通常是GUID——必须全局唯一)
  • UpdatedAt(DateTimeOffset——通过数据库触发器自动维护——用于增量同步)
  • CreateAt(DateTimeOffset——用作数据库分区的键以优化读取,但在其他情况下不使用)
  • Version(byte[]——时间戳——用于乐观并发/冲突解决)
  • Deleted(布尔值——用于在记录被删除时更新其他客户端——称为软删除)。

您的客户端需要在其客户端模型中具有所有这些字段,除了 Deleted(除非请求,否则不传输,并通过移动应用程序SDK自动处理已删除记录的离线同步清除)。

您没有说明后端或前端使用什么语言。 但是,在两种情况下都可以进行日志记录——您只需打开它,捕获异常等。 以下是一些参考资料:


目前后端是用C#编写的(只在这方面工作)。如果我在DataObject中添加CreatedAt,就会收到警告说它被覆盖了。那么这是否是我的问题呢?我会查看上面的链接。 - Zonus
需要一些时间来浏览,但我在第二个链接中找到了一个值得链接的页面,因为它概述了这些特定的DB字段:https://shellmonger.com/2016/04/29/30-days-of-zumo-v2-azure-mobile-apps-day-14-linking-existing-tables/ 谢谢! - Zonus
你知道为什么ID是一个字符串(varchar)而不是实际的GUID(uniqueidentifier)吗? - CodeGrue
另外,为什么UpdatedAt不能用于乐观并发?我们为什么需要额外的版本字段? - CodeGrue
它是一个字符串的原因是你可以使用任何全局唯一的东西 - GUID 是显而易见的,但并不是你唯一能使用的。只要两个不同的客户端不能设置相同的值,它就是一个好的值。例如,有些人使用客户端 ID(例如设备 ID)加上对该客户端唯一的递增数字。这取决于你。 - Adrian Hall
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接