在Azure移动服务控制器中添加相关数据库条目

时间:2015-08-24 11:33:25

标签: entity-framework azure-mobile-services

在我的Azure移动服务中,我有一个控制器类UserController : TableController<User>,其中包含一个get方法:

// GET tables/User/48D68C86-6EA6-4C25-AA33-223FC9A27959
public SingleResult<User> GetUser(string id)
{
    return Lookup(id);
}

我希望每次访问用户时记录,因此我向模型添加一个简单类型:

public class UserVisit : Microsoft.WindowsAzure.Mobile.Service.EntityData
{
    public string VisitingUser { get; set; }
    public DateTime TimeOfVisit { get; set; }
}

并在我的public DbSet<UserVisit> UserVisits { get; set; }类中包含属性VCollectAPIContext : DbContext(并使用代码优先迁移更新数据库)。

要在查询用户ID时将UserVisit添加到数据库,我将控制器方法更改为

// GET tables/User/48D68C86-6EA6-4C25-AA33-223FC9A27959
public async Task<SingleResult<User>> GetUser(string id)
{
    var userVisit = new UserVisit { VisitingUser = id, TimeOfVisit = DateTime.UtcNow };
    context.UserVisits.Add(userVisit);
    await context.SaveChangesAsync();
    return Lookup(id);
}

SaveChangesAsyncSystem.Data.Entity.Validation.DbEntityValidationException失败。在例外的EntityValidationErrors属性中挖掘我发现问题是“需要Id字段。”

这有点奇怪。 Id字段是基类Microsoft.WindowsAzure.Mobile.Service.EntityData中的一个属性,我希望在插入时自动添加。无论如何,我可以添加它和其他几个基类的属性:

// GET tables/User/48D68C86-6EA6-4C25-AA33-223FC9A27959
public async Task<SingleResult<User>> GetUser(string id)
{
    var userVisit = new UserVisit { Id = Guid.NewGuid().ToString(), Deleted = false, VisitingUser = id, TimeOfVisit = DateTime.UtcNow, CreatedAt = DateTimeOffset.Now };
    context.UserVisits.Add(userVisit);
    await context.SaveChangesAsync();
    return Lookup(id);
}

这次我得到System.Data.Entity.Infrastructure.DbUpdateException,因为我们“无法将值NULL插入到'CreatedAt'列中”。它在Add的调用中不为空。所以CreatedAt已在我的代码之外的某处设置为null,然后插入失败了!

我还尝试在控制器的初始化程序中设置EntityDomainManager<UserVisit> userVisitDomainManager;实例变量,然后将控制器get方法重写为

// GET tables/User/48D68C86-6EA6-4C25-AA33-223FC9A27959
public async Task<SingleResult<User>> GetUser(string id)
{
    var userVisit = new UserVisit { VisitingUser = id, TimeOfVisit = DateTime.UtcNow };
    await userVisitDomainManager.InsertAsync(userVisit);
    return Lookup(id);
}

失败并显示相同的消息,“无法将值NULL插入列'CreatedAt'”

我应该如何执行在我的控制器方法中插入相关数据项的看似简单的任务?

2 个答案:

答案 0 :(得分:2)

解决方案可能类似于this answer。我猜你的迁移没有使用Mobile Services SqlGenerator,所以一些自定义SQL设置没有得到应用。这意味着:

  • 我没有获得NEWID()的默认值 - 这说明您的&#34; Id字段是必需的&#34;错误。
  • CreatedAt没有获得SYSUTCDATETIME()的默认值 - 这与EntityData.CreatedAt上的[DatabaseGenerated]属性相结合,解释了&#34; NULL CreatedAt&#34;错误。

尝试根据上面的链接更新您的迁移,看看它是否适合您。

答案 1 :(得分:1)

按照 brettsam 的说明修复“必填字段”的问题。

在您的模型中添加:

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[TableColumn(TableColumnType.Id)]
public new string Id { get; set; }

添加实体时会自动生成GUID。