.NET 实体框架 - 代码优先设计为用户具有基于用户的设置的服务
本文关键字:用户 于用户 服务 设置 实体 代码 NET 框架 | 更新日期: 2023-09-27 18:31:14
我的 .NET WebAPI 项目与标识提供了多种(注册)用户可以使用的服务。对服务的访问权限是按用户授予的,因此用户 A 可以使用服务1、服务2 和服务 3,而用户 B 可以使用服务1、服务2、服务4 和服务 5。
每个服务都有 0..n 设置/配置。服务中使用的设置值还取决于用户。
例:
我们有用户Alice,Bob,Eve(当前默认ASP NET身份用户)和服务"随机数","搜索"和"天气预报"。随机数不需要设置,搜索需要使用搜索引擎,天气预报需要温度样式(摄氏度/华氏度)和预报提供者。
爱丽丝可以使用所有三种服务,谷歌作为搜索引擎,从 weather.com 开始以摄氏度为单位的天气预报。Bob 只能使用必应作为后端的搜索服务。Eve 可能会使用谷歌搜索和 accuweather 的华氏天气预报。
我坚持使用 EF 以代码优先方法设计表。任何帮助真的非常感谢。
public class Service
{
[Key]
public int Id {get;set;}
public string Name {get;set;}
}
public class UserService
{
[Key, Column(0)] // this creates a composite key
public int ServiceId {get;set;}
[Key, Column(1)] // this creates a composite key
public string UserId {get;set;}
}
因此,这会在您提供的用户和服务之间创建多对多关系。因此,您可以将一个用户添加到多个服务。以下是设置:
public class Settings
{
[Key]
public int Id {get;set;}
public int UserId {get;set;} // the user
public int ServiceId {get;set;} // the service
}
因此,要澄清的是,这是基于每个服务每个用户 1 个设置的设置。如果您希望每个服务的每个用户有多个设置,则必须将其设置为多对多。
希望这将是一个良好的开端。
需要注意的是,我不使用关系,即 public virtual Settings Settings {get;set;}
.我只是自己从数据库中加入它,如下所示。我特别不做多对多映射的用户关系,魔力实在是太大了!请参阅我在SO上的答案之一。我建议你永远不要对与 EF 的多对多关系使用延迟加载虚拟属性。
为了获得服务,我会这样做:
using (var context = new DbContext())
{
var usersWithServices = context.Users.GroupJoin(
context.UserServices,
u => u.Id,
j => j.UserId,
(user, @join) => new {
user,
@join
}).Select(a =>
a.join.GroupJoin(
context.Services,
j => j.ServiceId,
s => s.Id,
(@join, service) => new {
a.user,
@join,
service
})).ToList();
}
把它放到 LinqPad 中,它会像美女一样运行,虽然它是一头野兽。它基本上返回IEnumerable<IEnumerable<>>
,在最内层IEnumerable
是一个包含User
、UserService
、Service
的匿名对象。或者至少从 Linqpad 中,这就是我能看出的。把它放到VS中,你就会确切地知道你在处理什么。