.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 以代码优先方法设计表。任何帮助真的非常感谢。

.NET 实体框架 - 代码优先设计为用户具有基于用户的设置的服务

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是一个包含UserUserServiceService的匿名对象。或者至少从 Linqpad 中,这就是我能看出的。把它放到VS中,你就会确切地知道你在处理什么。