如何 POST/PATCH 到 Azure 移动服务上的多对多关系实体?
How to POST/PATCH to a many-to-many relationship entity on an Azure Mobile Services?
我一直在关注 Windows 开发中心的 the Field Engineer example project,以指导在我的模型上映射多对多关系。一直困扰我的是如何将条目插入到多对多关系中。
以我的模型为例:
一个组织可以有很多用户。
一个用户可以属于多个组织。
我的 User 模型 class 看起来像这样:
public class User
{
public User()
{
this.Organizations = new HashSet<Organization>();
}
public int Id { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string PasswordSalt { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool Active { get; set; }
public string Picture { get; set; }
public string PictureMimeType { get; set; }
public bool Confirmed { get; set; }
public string ConfirmationKey { get; set; }
[JsonIgnore]
public virtual ICollection<Organization> Organizations { get; set; }
}
我的UserDTOclass是这样的:
public class UserDTO : EntityData
{
public string Email { get; set; }
public string Password { get; set; }
public string PasswordSalt { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool Active { get; set; }
public string Picture { get; set; }
public string PictureMimeType { get; set; }
public bool Confirmed { get; set; }
public string ConfirmationKey { get; set; }
}
我的组织class:
public class Organization
{
public Organization()
{
this.Users = new List<User>();
}
public string Id { get; set; }
public string Title { get; set; }
public string LegalName { get; set; }
public string TaxReference { get; set; }
[JsonIgnore]
public virtual ICollection<User> Users { get; set; }
}
我的 OrganizationDTO class:
public class OrganizationDTO : EntityData
{
public string Title { get; set; }
public string LegalName { get; set; }
public string TaxReference { get; set; }
public virtual ICollection<UserDTO> Users { get; set; }
}
考虑到这些 classes,我创建了控制器 classes,我使用 AutoMapper[=79= 映射了 DTO 和模型 classes ]如下:
cfg.CreateMap<Organization, OrganizationDTO>()
.ForMember(organizationDTO => organizationDTO.Id,
map => map.MapFrom(organization => MySqlFuncs.LTRIM(MySqlFuncs.StringConvert(organization.Id))))
.ForMember(organizationDTO => organizationDTO.Users,
map => map.MapFrom(organization => organization.Users));
cfg.CreateMap<OrganizationDTO, Organization>()
.ForMember(organization => organization.Id,
map => map.MapFrom(organizationDTO => MySqlFuncs.LongParse(organizationDTO.Id)))
.ForMember(organization => organization.Users,
map => map.Ignore());
使用 Fluent API,我使用 EntityTypeConfiguration class 定义了这两个实体之间的关系这个:
public class UserEntityConfiguration : EntityTypeConfiguration<User>
{
public UserEntityConfiguration()
{
this.Property(u => u.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.HasMany<Organization>(u => u.Organizations).WithMany(o => o.Users).Map(uo =>
{
uo.MapLeftKey("UserId");
uo.MapRightKey("OrganizationId");
uo.ToTable("OrganizationsUsers");
});
}
}
我创建了一个 TableController class 来处理 UserDTO 和 OrganizationDTO,我插入新的 Users 或新的 Organizations 没问题,但是每个 TableController [=105 的端点=] 仅允许我据我所知单独添加 Users 或 Organizations。
要在 OrganizationsUser table 中创建一个条目,我该如何实现?
我在想 PATCH 请求应该是执行此操作的一种方法,但这是正确的方法吗?我必须为此定义一个 TableController 吗?如何公开此关系中元素的 Insert、Update、Select 和 Delete?要发送到端点的 JSON 是什么?
编辑 1
我试图在这样的组织中修补用户 属性:
url: serviceUrl/tables/Organization/1
JSON正文:
{
"users": [
{
"id": "1"
}
]
}
但这给了我一个错误:
The type of one of the primary key values did not match the type
defined in the entity. See inner exception for details.
Parameter name: keyValues
Inner Exception:
The argument types 'Edm.Int32' and 'Edm.String' are incompatible for
this operation. Near WHERE predicate, line 1, column 78.
如果我没记错的话,我似乎需要将发送的字符串映射到使用 Fluent API 创建的连接 table 中,但是如何映射连接 table 用 Fluent API 定义? PATCH 是这样做的方法吗?还是有别的办法?
我认为 PATCH 应该可以工作,但我不是 automapper 方面的专家。
如果您在每个组织中只有几个用户,另一种选择是在您的后端创建代表连接表的视图。请参阅我在此论坛主题中的帖子,以获取有关其工作原理的示例:https://social.msdn.microsoft.com/Forums/azure/en-US/4c056373-d5cf-4ca6-9f00-f152d2b01372/best-practice-for-syncing-related-tables-in-offline-mode?forum=azuremobile。这种方法的优点是它真正简化了客户端数据模型,而且它不需要知道任何关于外键的事情。
但是,问题是您最终可能会得到重复的 users/organizations,这会在客户端数据库中占用更多 space。但是,由于我的示例设置 UpdatedAt 和版本的方式,您将获得所有更新,例如,一旦用户的详细信息发生更改。
我一直在关注 Windows 开发中心的 the Field Engineer example project,以指导在我的模型上映射多对多关系。一直困扰我的是如何将条目插入到多对多关系中。
以我的模型为例:
一个组织可以有很多用户。
一个用户可以属于多个组织。
我的 User 模型 class 看起来像这样:
public class User
{
public User()
{
this.Organizations = new HashSet<Organization>();
}
public int Id { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string PasswordSalt { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool Active { get; set; }
public string Picture { get; set; }
public string PictureMimeType { get; set; }
public bool Confirmed { get; set; }
public string ConfirmationKey { get; set; }
[JsonIgnore]
public virtual ICollection<Organization> Organizations { get; set; }
}
我的UserDTOclass是这样的:
public class UserDTO : EntityData
{
public string Email { get; set; }
public string Password { get; set; }
public string PasswordSalt { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool Active { get; set; }
public string Picture { get; set; }
public string PictureMimeType { get; set; }
public bool Confirmed { get; set; }
public string ConfirmationKey { get; set; }
}
我的组织class:
public class Organization
{
public Organization()
{
this.Users = new List<User>();
}
public string Id { get; set; }
public string Title { get; set; }
public string LegalName { get; set; }
public string TaxReference { get; set; }
[JsonIgnore]
public virtual ICollection<User> Users { get; set; }
}
我的 OrganizationDTO class:
public class OrganizationDTO : EntityData
{
public string Title { get; set; }
public string LegalName { get; set; }
public string TaxReference { get; set; }
public virtual ICollection<UserDTO> Users { get; set; }
}
考虑到这些 classes,我创建了控制器 classes,我使用 AutoMapper[=79= 映射了 DTO 和模型 classes ]如下:
cfg.CreateMap<Organization, OrganizationDTO>()
.ForMember(organizationDTO => organizationDTO.Id,
map => map.MapFrom(organization => MySqlFuncs.LTRIM(MySqlFuncs.StringConvert(organization.Id))))
.ForMember(organizationDTO => organizationDTO.Users,
map => map.MapFrom(organization => organization.Users));
cfg.CreateMap<OrganizationDTO, Organization>()
.ForMember(organization => organization.Id,
map => map.MapFrom(organizationDTO => MySqlFuncs.LongParse(organizationDTO.Id)))
.ForMember(organization => organization.Users,
map => map.Ignore());
使用 Fluent API,我使用 EntityTypeConfiguration class 定义了这两个实体之间的关系这个:
public class UserEntityConfiguration : EntityTypeConfiguration<User>
{
public UserEntityConfiguration()
{
this.Property(u => u.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.HasMany<Organization>(u => u.Organizations).WithMany(o => o.Users).Map(uo =>
{
uo.MapLeftKey("UserId");
uo.MapRightKey("OrganizationId");
uo.ToTable("OrganizationsUsers");
});
}
}
我创建了一个 TableController class 来处理 UserDTO 和 OrganizationDTO,我插入新的 Users 或新的 Organizations 没问题,但是每个 TableController [=105 的端点=] 仅允许我据我所知单独添加 Users 或 Organizations。
要在 OrganizationsUser table 中创建一个条目,我该如何实现?
我在想 PATCH 请求应该是执行此操作的一种方法,但这是正确的方法吗?我必须为此定义一个 TableController 吗?如何公开此关系中元素的 Insert、Update、Select 和 Delete?要发送到端点的 JSON 是什么?
编辑 1
我试图在这样的组织中修补用户 属性:
url: serviceUrl/tables/Organization/1
JSON正文:
{
"users": [
{
"id": "1"
}
]
}
但这给了我一个错误:
The type of one of the primary key values did not match the type defined in the entity. See inner exception for details. Parameter name: keyValues
Inner Exception:
The argument types 'Edm.Int32' and 'Edm.String' are incompatible for this operation. Near WHERE predicate, line 1, column 78.
如果我没记错的话,我似乎需要将发送的字符串映射到使用 Fluent API 创建的连接 table 中,但是如何映射连接 table 用 Fluent API 定义? PATCH 是这样做的方法吗?还是有别的办法?
我认为 PATCH 应该可以工作,但我不是 automapper 方面的专家。
如果您在每个组织中只有几个用户,另一种选择是在您的后端创建代表连接表的视图。请参阅我在此论坛主题中的帖子,以获取有关其工作原理的示例:https://social.msdn.microsoft.com/Forums/azure/en-US/4c056373-d5cf-4ca6-9f00-f152d2b01372/best-practice-for-syncing-related-tables-in-offline-mode?forum=azuremobile。这种方法的优点是它真正简化了客户端数据模型,而且它不需要知道任何关于外键的事情。
但是,问题是您最终可能会得到重复的 users/organizations,这会在客户端数据库中占用更多 space。但是,由于我的示例设置 UpdatedAt 和版本的方式,您将获得所有更新,例如,一旦用户的详细信息发生更改。