DbSet、模型构建器和 EF 导航属性

2024-04-16

我正在尝试实现一个多租户应用程序,在其中通过租户对象查询数据库,而不是直接从上下文中查询。在我拥有这个之前:

public User GetUserByEmail(string email)
    {
        using (var db = CreateContext())
        {
            return db.Users.FirstOrDefault(u => u.Email.Equals(email, StringComparison.OrdinalIgnoreCase));
        }
    }

现在我有这个:

public User GetUserByEmail(string email)
    {
        using (var db = CreateContext())
        {
            return _tenant.Users.FirstOrDefault(u => u.Email.Equals(email, StringComparison.OrdinalIgnoreCase));
        }
    }

其中租户如下:

public class Tenant
{
    public Tenant()
    {
    }

    [Key]
    [Required]
    public int TenantId { get; set; }

    public virtual DbSet<User> Users { get; set; }
    // etc
}

我的用户模型具有以下内容:

public virtual List<Tenant> Tenants { get; set; }

在我的上下文配置中,我有以下内容:

modelBuilder.Entity<Tenant>()
        .HasMany(e => e.Users)
        .WithMany()
        .Map(m =>
        {
            m.ToTable("UserTenantJoin");
            m.MapLeftKey("TenantId");
            m.MapRightKey("UserId");
        });

但我遇到了一个问题,因为 DbSet 与上面的 ModelBuilder 不兼容 - 它对 HasMany 说不能从使用中推断出 DbSet 的使用感到窒息。

我使用 ICollection 代替,但随后在我的服务层中所有调用_tenant.Users.Include(stuff), or Find(),并且其他数据库查询中断。

如果我使用 ICollection,则会中断的服务方法示例:

   public User GetUserWithInterestsAndAptitudes(string username)
    {
        using (var db = CreateContext())
        {
            return _tenant.Users.  // can't use .Include on ICollection
                Include(u => u.Relationships).
                Include(u => u.Interests).
                Include(u => u.Interests.Select(s => s.Subject)).
                Include(u => u.Interests.Select(s => s.Aptitude)).
                FirstOrDefault(s => s.Username.Equals(username, StringComparison.OrdinalIgnoreCase));
        }
    }

我希望有一个解决方案可以让我保持导航属性可查询,而无需重新构建我的服务层。

一种选择是我将所有内容恢复为使用上下文db.Users,然后为每个查询添加另一个条件.Where(u => u.TenantId == _tenant.TenantId)- 但我正在努力避免这种情况。

任何帮助将不胜感激。


我有一个类似于您试图避免的解决方案。

我有一个真正的 DbContext,只能通过 TenantContext 访问。

public class RealContext
{
     public DbSet<User> Users { get; set; }
     [...]
}

public class TenantContext 
{
    private RealContext realContext;
    private int tenantId;
    public TenantContext(int tenantId)
    {
        realContext = new RealContext();
        this.tenantId= tenantId;
    }
    public IQueryable<User> Users { get { FilterTenant(realContext.Users); }     }

    private IQueryable<T> FilterTenant<T>(IQueryable<T> values) where T : class, ITenantData
    {
         return values.Where(x => x.TenantId == tenantId);
    }
    public int SaveChanges()
    {
        ApplyTenantIds();
        return realContext.SaveChanges();
    }
}

使用此方法,我确信在没有获得正确租户的情况下无法发送查询。为了从上下文中添加和删除项目,我使用这两种通用方法。

public void Remove<T>(params T[] items) where T : class, ITenantData
{
    var set = realContext.Set<T>();
    foreach(var item in items)
        set.Remove(item);
}

public void Add<T>(params T[] items) where T : class, ITenantData
{
    var set = realContext.Set<T>();
    foreach (var item in items)
        set.Add(item);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DbSet、模型构建器和 EF 导航属性 的相关文章

  • 使用 Xamarin.Forms 和 Zxing 生成 QR 码

    我在网上看到了很多关于这个的内容 旧帖子 但似乎没有什么对我有用 我正在尝试从字符串中生成二维码并将其显示在应用程序中 这就是我一开始的情况 qrCode new ZXingBarcodeImageView BarcodeFormat Ba
  • C# Outlook 从收件人获取 CompanyName 属性

    我目前正在使用 C 编写 Outlook 2010 AddIn 我想要的是从我从 AppointmentItem 中提取的 Recipient 对象中获取 CompanyName 属性 因此 有了 AppointmentItem 的收件人
  • 具有多个谓词的 C++11 算法

    功能如std find if来自algorithmheader 确实很有用 但对我来说 一个严重的限制是我只能为每次调用使用 1 个谓词count if 例如给定一个像这样的容器std vector我想同时应用相同的迭代find if 多个
  • 以下 PLINQ 代码没有改进

    我没有看到使用以下代码的处理速度有任何改进 IEnumerable
  • 为什么 C# 中同一类型的隐式和显式运算符不能共存? [复制]

    这个问题在这里已经有答案了 为什么同一类中两个相同类型的运算符 显式和隐式 不能共存 假设我有以下内容 public class Fahrenheit public float Degrees get set public Fahrenhe
  • 类中是否可以有虚拟类声明?

    我正在为个人项目中框架的各个组件设置一个接口 我突然想到了一些我认为可能对接口有用的东西 我的问题是这是否可能 class a public virtual class test 0 class b public a public clas
  • 从时间列表中查找最接近的时间

    所以 这是场景 我有一个带有创建时间的文件 我想从该文件的创建时间最接近或相等的时间列表中选择一个时间 完成此操作的最佳方法是什么 var closestTime listOfTimes OrderBy t gt Math Abs t fi
  • 使用 ELMAH 记录 WCF 服务的异常

    我们正在使用优秀的ELMAH http code google com p elmah处理 ASP NET 3 5 Web 应用程序中未处理的异常 这对于除使用 REST 功能使用的 WCF 服务之外的所有站点都非常有效 当操作方法中发生应
  • C# Winforms Designer 无法打开,因为它无法在同一程序集中找到类型

    我收到以下错误 找不到类型 My Special UserControl 请确保引用包含此类型的程序集 如果此类型是您的开发项目的一部分 请确保已使用当前平台或任何 CPU 的设置成功构建该项目 但没有任何意义的是My Special Us
  • 检测 TextBox 中的 Tab 键按下

    I am trying to detect the Tab key press in a TextBox I know that the Tab key does not trigger the KeyDown KeyUp or the K
  • 编写具有多种类型的泛型扩展方法时的类型推断问题

    我正在为 IEnumerable 编写一个通用扩展方法 用于将对象列表映射到另一个映射对象列表 这就是我希望该方法的工作方式 IList
  • 使用 Unity 在 C# 中发送 http 请求

    如何使用 Unity 在 C 中发送 HTTP GET 和 POST 请求 我想要的是 在post请求中发送json数据 我使用Unity序列化器 所以不需要 新的 我只想在发布数据中传递一个字符串并且能够 将 ContentType 设置
  • 如何测试某些代码在 C++ 中无法编译? [复制]

    这个问题在这里已经有答案了 可能的重复 单元测试编译时错误 https stackoverflow com questions 605915 unit test compile time error 我想知道是否可以编写一种单元测试来验证给
  • 在二进制数据文件的标头中放入什么

    我有一个模拟 可以读取我们创建的大型二进制数据文件 10 到 100 GB 出于速度原因 我们使用二进制 这些文件依赖于系统 是从我们运行的每个系统上的文本文件转换而来的 所以我不关心可移植性 当前的文件是 POD 结构的许多实例 使用 f
  • 使用 boost 异步发送和接收自定义数据包?

    我正在尝试使用 boost 异步发送和接收自定义数据包 根据我当前的实现 我有一些问题 tcpclient cpp include tcpclient h include
  • 运行 xunit 测试时无法将输出打印到控制台窗口

    public class test2InAnotherProject private readonly ITestOutputHelper output public test2InAnotherProject ITestOutputHel
  • 通过 SharpDX 渲染 Direct2D 图像时如何使用内存流而不是文件?

    设置 考虑使用给定的临时程序SharpDX http code google com p sharpdx Direct 库的托管包装器 用于渲染位图并将其保存为 PNG namespace ConsoleApplication5 using
  • 如何知道 HTTP 请求标头值是否存在

    我确信这很简单 但是却让我感到厌烦 我在 Web 应用程序中使用了一个组件 它在 Web 请求期间通过添加标头 XYZComponent true 来标识自身 我遇到的问题是 如何在视图中检查此组件 以下内容不起作用 if Request
  • Emacs C++,打开相应的头文件

    我是 emacs 新手 我想知道 是否有在头文件 源文件和相应的源文件 头文件之间切换的快捷方式 是否有像通用 emacs 参考卡那样的参考卡 Thanks There s ff find other file 您可以使用以下方法将其绑定到
  • 如何在c中断言两个类型相等?

    在 C 中如何断言两种类型相等 在 C 中 我会使用 std is same 但搜索 StackOverflow 和其他地方似乎只能给出 C 和 C 的结果 在C中没有办法做到这一点吗 请注意 这不是询问变量是否具有某种类型 而是询问两个类

随机推荐

  • Ansible with_items 与循环

    使用有什么区别带有项目 https docs ansible com ansible 2 4 playbooks loops html vs loops http docs ansible com ansible latest user g
  • 设置按钮在悬停时显示

    我在 Angular 4 材料表单元格中有一个按钮 我希望仅当鼠标悬停在表行上时才显示该按钮
  • 在 C# 中,如何在不使用 Bitmap.MakeTransparent() 的情况下将图像设置为透明背景?

    我想将图像设置为具有透明背景 但我不想用透明度替换特定颜色的所有像素 更具体地说 该图像是通过 IShellItemImageFactory GetImage 获取的文件夹的缩略图 这给了我一个位图 如 Windows 资源管理器缩略图视图
  • 如何在 Inno Setup 中使用 GetVolumeInformation?

    我需要在使用 Inno Setup 创建的安装过程中获取驱动器号的卷序列号 我知道 DLL 函数可以导入到 Inno 中 但我对它还很陌生 并且在使其工作时遇到一些问题 我知道 kernel32 中的 GetVolumeInformatio
  • 使用连接、分组依据和聚合函数的 SQL 选择查询

    我有两个带有以下字段的表 emp table emp id emp name salary increase emp id inc date inc amount 我需要编写一个查询 其中提供员工详细信息 员工加薪的次数 最大加薪金额以及加
  • 可安装发动机安装在什么路径上

    我需要从可安装引擎的布局内部知道它当前安装在什么路径上 该怎么做呢 例如 我的routes rb 包含以下行 mount BackendCore Engine gt backend 从 BackendCore 内部 我需要访问 backen
  • BLL和DAL之间的通信

    解决方案设置 DAL 类库 BLL 类库 常见 类库 一些常见功能 枚举 日志记录 异常等 应用程序 1 Windows 应用程序 应用程序2 Windows应用程序 WebApp 网络应用程序 假设我有一个Customer实体 即 SQL
  • 在 R 中生成可能排列的随机、非重复子集

    Given p离散变量 我想随机选择 k他们可能的排列 换句话说 对于变量a in 0 1 and b in 1 2 3 两个随机排列将是 0 2 and 1 3 我想在不首先生成所有可能排列的表的情况下生成这些变量 因为随着变量数量及其可
  • 将以毫秒为单位的日期时间转换为双精度或整数?

    我有一个看起来不错的字符串 如下所示 TimeString 2011 01 02 22 06 52 091 现在我想将其转换为双精度数 并将其保存为双精度数 我是用c 做的 我该怎么做呢 网上实在找不到答案 Edit 时间是一种金融货币报价
  • Google Analytics“用户计数”与大查询“用户计数”不匹配

    我们的 Google Analytics 用户计数 与我们的大查询 用户计数 不匹配 我计算得正确吗 通常 GA 和 BQ 非常接近 尽管不完全一致 最近 GA 与 BQ 中的用户数并不一致 我们的 每个用户的会话数 通常非常正常分配 在过
  • 如何编写自定义操作 DLL 以在 MSI 中使用?

    这是我打算自己回答的问题 但请随意添加其他方法来完成此任务 我正在打包一个应用程序以用于各种配置 并且我确定在 MSI 中执行自定义逻辑的最可靠方法是编写我自己的自定义操作 DLL 该 DLL 能够从 PROPERTY 表中读取 写入 终止
  • 在 Monogame 中使用 BMP 图像作为字体

    有没有办法使用 BMP 图像加载自定义字体 我在网上看到了 Microsoft 提供的解决方案 但在尝试运行此解决方案时 我不断收到内容加载异常 看起来这曾经适用于 XNA 但对于 Monogame 可能不再是这样了 我想要自己的自定义字体
  • Git:推送到多个远程

    Short 如果您将多个远程存储库链接到本地 文件 是否有一种方法可以同时推送到它们 Long 由于工作原因 我的代码必须使用gitlab和github遥控器 因此 一旦我进行了一些本地更改 我就想更新这两个存储库 我的 git confi
  • 重新渲染子视图后,主干事件会多次触发

    我们有一个由侧边栏和几个子视图组成的主干视图 为简单起见 我们决定让侧边栏和子视图由单个视图管理render功能 但是 那click edit单击侧边栏项目之一后 事件似乎会多次触发 例如 如果我从 常规 开始并单击 edit then h
  • Vim: set langmap=e;h 破坏 supertab 插件

    我是 Vim 新手 正在尝试设置一些插件 到目前为止我已经安装了 Pathogen pyflakes 和 supertab 后者似乎不起作用 紧迫tab而在插入模式下只需写入字符串
  • 如何从 UWP(又名 .NET Core)中的 Type 对象获取 Assembly

    Type 类在 NET Framework 中有一个Assembly 属性 然而 当您编写使用 NET Core 的 UWP 时 此属性就消失了 仅 AssemblyQualifiedName 属性可用 我怎样才能从这个名字进入Assemb
  • R:如何用文本框注释 ggplot?

    我希望添加一个小的白色文本框 并在 ggplot 绘图的正文中添加自定义文本 我要添加的文本是为了标识我要添加到绘图中的水平线 ggplot cb emp geom point aes x grossunits y rate color a
  • 在 StringTokenizer 中使用多个分隔符

    我想知道如何在 java 中使用 StringTokenizer 的多个分隔符 例如其中之一 将作为分隔符出现 而且一次只会有一个 Use the 有两个参数的构造函数 http docs oracle com javase 6 docs
  • r - 如何清除 rJava 使用的内存?

    我正在使用 xlsx 包创建工作簿 工作表 将数据写入工作表 然后保存工作簿 然而 当我多次重复这组操作时 我开始出现错误消息 gt Error in jcheck silent FALSE java lang OutOfMemoryErr
  • DbSet、模型构建器和 EF 导航属性

    我正在尝试实现一个多租户应用程序 在其中通过租户对象查询数据库 而不是直接从上下文中查询 在我拥有这个之前 public User GetUserByEmail string email using var db CreateContext