【问题标题】:Modeling mongodb stored referenced relationships in .net core在 .net 核心中建模 mongodb 存储的引用关系
【发布时间】:2019-07-24 02:23:18
【问题描述】:

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

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

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

在 mongo 中有两个集合,Accounts 和 Users。用户属于其父帐户。在这种情况下,我不想采用嵌入式文档路线,因此每个用户文档中都会有一个 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 中概述的方法之一进行连接本身。但我的问题是,是否有关于如何设置我的实体和模型以使存储尽可能干净的最佳实践?

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

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

属性

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

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

然后,User 模型可以具有类似

的属性
 public string AccountName { get; set; }

它们使用映射器填充。

当您想引用相关对象而不是嵌入它们时,这是最好的设置方法吗?这里有什么我遗漏的问题吗?

【问题讨论】:

    标签: c# mongodb asp.net-core-mvc


    【解决方案1】:

    看看下面的代码。它使用我的库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();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-08
      • 2020-08-05
      • 1970-01-01
      • 2021-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多