我正在使用 servicestack 编写用户服务,当请求用户资源时,我想以各自 URL 的形式返回实体集合。资源是被请求用户的朋友。
我当前的用户实体
[RestService("/users")]
[RestService("/users/{Id}")]
[Alias("Users")]
public class User
{
[AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public string CellPhoneNumber { get; set; }
public string EmailAddress { get; set; }
public DateTime CreatedDate { get; set; }
}
本质上,在我的 SQLite 数据库中,我会有一个名为“Friendships”的表来表达关系。桌子应该像这样工作得很好
ID PK INT NOT NULL
UserID1 FK INT NOT NULL
UserID2 FK INT NOT NULL
我需要一个“友谊”实体来表达这一点吗?我应该向我的用户实体添加/更改什么以让 ServiceStack 将其与友谊集合一起返回?
我认为可能是这样的友谊实体
[RestService("/users/{Id}/friends")]
[Alias("Friendships")]
public class Friendship
{
[AutoIncrement]
public int Id { get; set; }
public int UserId1 { get; set; }
public int UserId2 { get; set; }
}
并且在处理请求时,返回用户朋友的资源 URL 集合。我不确定如何继续前进,并且可以使用一些提示/建议。
结果实施
我最终将我的 Friendships 表保存在数据库中,但没有实现 FriendshipService 类,而是使用了类似于 myz 建议的东西。
[RestService("/users/{Id}/friends")]
public class UserFriends
{
public int Id { get; set; }
}
如您所见,我一直使用mythz 的UserFriends 实体。尽管符合我的需要,但我的服务等级有所不同。他/她提出的解决方案没有解决的问题是有问题的用户实体可以是 UserId1 或 UserId2。所以这就是用我的服务类来解决问题的。
public class UserFriendsService : RestServiceBase<UserFriends>
{
public IDbConnectionFactory DbFactory { get; set; }
public override object OnGet(UserFriends request)
{
if (request.Id != default(int))
{
User user = DbFactory.Exec(dbCmd => dbCmd.GetById<User>(request.Id));
var friendIds = DbFactory
.Exec(dbCmd => dbCmd.Where<Friendship>("UserId1", request.Id).Select(fs => fs.UserId2))
.Union(DbFactory.Exec(dbCmd => dbCmd.Where<Friendship>("UserId2", request.Id)).Select(fs => fs.UserId1));
List<User> friends = DbFactory.Exec(dbCmd => dbCmd.GetByIds<User>(friendIds));
return friends;
}
else
{
return DbFactory.Exec(dbCmd => dbCmd.Select<User>());
}
}
}
我可以通过使用选定的 Id 并dbCmd.GetById<User>()
在初始查询中使用它们来选择用户实体而不是朋友 Id,但我认为这会使代码更加复杂且难以阅读。