在.net core中对mongodb存储引用关系进行建模

2024-02-06

我是 mongo 的新手,在处理引用关系并在 .net core 中对其进行建模时,我正在寻找一些有关最佳实践的指导。

是的,这就是通常的“加入 mongodb??”问题。但我还没有找到一个好的答案。

为了简单起见,假设我有一个简单的 API,正在使用控制器构建来管理用户和帐户。

在 mongo 中有两个集合,帐户和用户。用户属于其父帐户。在这种情况下,我不想采用嵌入文档路径,因此每个用户文档中都会有一个 AccountID,用于将用户链接回其父帐户。

我当前在 .net 中的实体是:

public class User
{

    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }

    [BsonElement("firstName")]
    public string FirstName { get; set; }

    [BsonElement("lastName")]
    public string LastName { get; set; }

    [BsonElement("email")]
    public string Email { get; set; }

    [BsonElement("status")]
    public string Status { get; set; }

    [BsonElement("type")]
    public string Type { get; set; }

    [BsonElement("createdDateTime")]
    public DateTime CreatedDateTime { get; set; }

    [BsonElement("modifiedDateTime")]
    public DateTime ModifiedDateTime { get; set; }

    [BsonRepresentation(BsonType.ObjectId)]
    [BsonElement("accountId")]
    public string AccountId { get; set; }

}

 public class Account
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }

    [BsonElement("name")]
    public string Name { get; set; }

    [BsonElement("status")]
    public string Status { get; set; }

    [BsonElement("type")]
    public string Type { get; set; }

    [BsonElement("createdDateTime")]
    public DateTime CreatedDateTime { get; set; }

    [BsonElement("modifiedDateTime")]
    public DateTime ModifiedDateTime { get; set; }

}

然后使用控制器中的 AutoMapper 将它们映射到模型

public class UserModel
{

    [Required]
    public string FirstName { get; set; }

    [Required]
    public string LastName { get; set; }

    [Required]
    public string Email { get; set; }

    [Required]
    public string Status { get; set; }

    [Required]
    public string Type { get; set; }

    [Required]
    public DateTime CreatedDateTime { get; set; }

    [Required]
    public DateTime ModifiedDateTime { get; set; }

    [Required]
    public string AccountId { get; set; }

}

public class AccountModel
{

    [Required]
    public string Name { get; set; }

    [Required]
    public string Status { get; set; }

    [Required]
    public string Type { get; set; }

    [Required]
    public DateTime CreatedDateTime { get; set; }

    [Required]
    public DateTime ModifiedDateTime { get; set; }

}

以及使用映射器的控制器方法的示例:

[HttpGet]
    public async Task<ActionResult<List<AccountModel>>> Get()
    {
        try
        {
            var results = await _repository.Get();

            return _mapper.Map < List < AccountModel >>(results);
        }
        catch (Exception ex)
        {
            return this.StatusCode(StatusCodes.Status500InternalServerError, "Database Failure");
        }


    }

一切都很好。我可以调用控制器方法,获取数据,并将其从实体映射到模型,然后从控制器方法返回。

问题是这样的:我想返回带有帐户信息的用户数据(例如:帐户名称)。所以只是一个简单的加入。

我想我已经掌握了如何使用本文中概述的方法之一进行连接本身answer https://stackoverflow.com/questions/50530363/aggregate-lookup-with-c-sharp。但我的问题是,是否有关于如何设置我的实体和模型以使存储尽可能干净的最佳实践?

我正在考虑向用户实体添加一个属性来存储相关帐户。用 [BsonIgnore] 属性标记,以便它远离数据库。

 [BsonIgnore]
    public Account Account { get; set; }

该物业

       [BsonRepresentation(BsonType.ObjectId)]
    [BsonElement("accountId")]
    public string AccountId { get; set; }

仍保留在用户实体中,因此引用被保留。

然后,用户模型可以具有如下属性

 public string AccountName { get; set; }

他们使用映射器进行填充。

当您想要引用相关对象而不是嵌入它们时,这是设置它的最佳方法吗?我在这里缺少一些陷阱吗?


看看下面的代码。它使用我的图书馆MongoDB.实体 https://github.com/dj-nitehawk/MongoDB.Entities它内置支持实体之间的一对一、一对多和多对多关系。

using MongoDB.Entities;
using System.Linq;

namespace StackOverflow
{
    public class Program
    {
        public class Account : Entity
        {
            public string Name { get; set; }
            public Many<User> Users { get; set; }

            public Account() => this.InitOneToMany(() => Users);
        }

        public class User : Entity
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public One<Account> Account { get; set; }

            [Ignore]
            public string AccountName { get; set; }
        }

        private static void Main(string[] args)
        {
            new DB("test");

            var account = new Account { Name = "parent account" };
            account.Save();

            var user = new User
            {
                FirstName = "dave",
                LastName = "mathews",
                Account = account.ToReference()
            };
            user.Save();

            account.Users.Add(user);

            //find parent by ID
            var parent = DB.Find<Account>().One(account.ID);

            //get first user of parent
            var dave = parent.Users.ChildrenQueryable()
                                   .FirstOrDefault();

            //get dave's account
            var davesAccount = dave.Account.ToEntity();

            //get dave with account name filled in by a single mongo query
            var daveExtra = (from u in DB.Queryable<User>().Where(u => u.ID == dave.ID)
                             join a in DB.Queryable<Account>() on u.Account.ID equals a.ID
                             select new User
                             {
                                 ID = u.ID,
                                 FirstName = u.FirstName,
                                 LastName = u.LastName,
                                 AccountName = a.Name
                             }).SingleOrDefault();
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在.net core中对mongodb存储引用关系进行建模 的相关文章

  • SOAP Web 服务:多台服务器,一个接口

    我有一个场景 需要任意数量的服务器来提供相同的 SOAP Web 服务 我想生成一组代理类 并能够为它们提供一个位置 以便在运行时将它们指向不同的服务器 不幸的是 看起来好像wsdl port节点 子节点wsdl service 要求对特定
  • 无法在 CUDA 中找到 1 到 100 数字的简单和?

    我正在研究使用 CUDA 的图像处理算法 在我的算法中 我想使用 CUDA 内核找到图像所有像素的总和 所以我在cuda中制作了内核方法 来测量16位灰度图像的所有像素的总和 但我得到了错误的答案 所以我在cuda中编写了一个简单的程序来查
  • 如何使用T4从一个模板同时生成两个文件?

    我遇到的情况是 我需要生成两个 CSharp 代码文件 它们的代码几乎相同 但方法的输入和输出类型的命名空间不同 事实上 每个文件都针对特定国家 地区 并且类型来自特定国家 地区的 WSDL 我正在围绕服务编写一些包装器 逻辑完全相同 但从
  • CMake(Ninja 后端)使用 /MT 编译

    我有一个类似的问题CMake 使用 MT 而不是 MD 进行编译 https stackoverflow com questions 14172856 cmake compile with mt instead of md但有一些差异 我正
  • 如何以编程方式删除受信任的根证书颁发机构中的证书?

    我需要能够从组织中的每台电脑中删除特定的证书 是的 我可以逐个座位 但我要到周四才能完成 而且我没有人力逐个座位 是否有使用 C 的编程方式来执行此操作 我认为你不需要编写任何 C 看看certmgr exe del http msdn m
  • Visual Studio 2013 调试器显示 std::string 的奇怪值

    我有一个大型的 cmake 生成的解决方案 其中包含许多项目 由于某种原因 我无法查看字符串的内容 因为根据调试器 Bx Buf含有一些垃圾 text c str 正确返回 Hello 该问题不仅仅发生在本地字符串上 返回的函数std st
  • 获取列表框中视图中的项目

    我有一个 ListBox 其属性 VirtualizingStackPanel VirtualizationMode 设置为 回收 我正在绑定一个自定义集合 实现IList and IList
  • Windows Phone 7 - ScrollViewer 值已更改

    我一直在寻找解决方案 但无法找到正确的解决方案 我的网格宽度为 960 并且有ScrollViewer在里面 现在我想知道滚动时滚动的值 水平偏移 我找到的所有解决方案都是针对 wpf silverlight 的 它对我不起作用 Edit
  • 加载 QPixmap 数据的更好方法

    更好的方法来做到这一点 没有QImage QImage image width height QImage Format RGB888 memcpy image bits m frameRGB gt data 0 height width
  • 公交车公共交通算法

    我正在开发一个可以查找公交路线的离线 C 应用程序 我可以提取时间表 巴士 路线数据 我正在寻找适用于基本数据的最简单的解决方案 可以使用什么算法来查找从巴士站 A 到巴士站 B 的路线 是否有适用于 C Java 的开源解决方案 数据库的
  • 自己绘制的WPF自定义滑块

    这是我关于堆栈溢出的第一个问题 所以不要踢它 我在尝试创建 Mac 风格的滑块控件时遇到问题 我已经发现这个解决方案 http www codeproject com KB miscctrl MAC Slider aspx我已经在我的解决方
  • 从图像创建半透明光标

    是否可以从图像创建光标并使其半透明 我目前正在拍摄自定义图像并覆盖鼠标光标图像 如果我可以将其设为半透明 那就太好了 但不是必需的 销售人员喜欢闪亮的 目前正在做这样的事情 Image cursorImage customImage Get
  • 注入包含接口的所有已注册实现的 Enumerable

    给出以下接口 public interface IMyProcessor void Process 我希望能够注册多个实现 并让我的 DI 容器将它们的可枚举注入到这样的类中 public class MyProcessorLibrary
  • 更改私有模块片段是否会导致模块重新编译?

    On 此页面有关 C 20 模块功能 https www modernescpp com index php c 20 modules private module fragment and header units 我发现了这样的说法 借
  • 如何从 Powerpoint 2010 导出电影?

    如何使用 MS Office PIA 主互操作程序集 或其他方式以编程方式将嵌入视频从 powerpoint 2010 导出到外部文件 在演示文稿中嵌入视频是 Powerpoint 2010 中的一项新功能 我找不到解决方案 PPTX 文件
  • 将 AutomationID 与 ListView 结合使用

    我正在尝试将 AutomationId 附加到列表视图中的项目 理想情况下 将项目名称绑定到显示的项目
  • 如何通过引用文档查询嵌入文档?

    我正在使用 Doctrine ODM 但在通过引用文档查询嵌入文档时遇到问题 考虑以下文件
  • MPI - 发送和接收列

    我需要从一个进程发送矩阵列并从另一个进程接收它 我尝试运行以下程序 但得到了一个奇怪的结果 至少我这么认为 仅复制矩阵的第一个元素 某些矩阵元素会发生意外变化 include
  • 跟踪白色背景中的白球(Python/OpenCV)

    我在 Python 3 中使用 OpenCV 来检测白场上的白 黑球 并给出它的精确 x y 半径 和颜色 我使用函数 cv2 Canny 和 cv2 findContours 来找到它 但问题是 cv2 Canny 并不总是检测到圆的完整
  • java有类似C#的属性吗? [复制]

    这个问题在这里已经有答案了 C 属性 我的意思是 get 和 set 方法 是一个非常有用的功能 java 也有类似 C 的属性吗 我的意思是我们如何在 java 中实现类似以下 C 代码的内容 public string Name get

随机推荐