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データベースには、関係を表す「友情」というテーブルがあります。テーブルはこのようにうまく機能するはずです
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クラスを実装せず、代わりにmythzが提案したものと同様のものを使用しました。
[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の代わりにユーザーエンティティを選択することもできますが、それではコードがより複雑になり、読みにくくなると思います。