在.net Core中对mongodb存储的引用关系进行建模 [英] Modeling mongodb stored referenced relationships in .net core

查看:51
本文介绍了在.net Core中对mongodb存储的引用关系进行建模的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm new to mongo and I'm looking for some guidance on best practices when dealing with referenced relationships and modeling them in .net core.

是的,这是通常的加入mongodb吗??"问题.但是我还没有找到一个好的答案.

Yes, it's the usual "joins in mongodb??" question. But I haven't found a good answer to this.

为简单起见,可以说我有一个简单的API,我正在使用控制器来管理用户和帐户.

To make this simple, lets say I've got a simple API i'm building out with controllers to manage users and accounts.

在mongo中,有两个集合,即帐户"和用户".用户属于其父帐户.在这种情况下,我不想使用嵌入式文档路线,因此每个用户文档中都将包含一个AccountID,以将用户链接回其父帐户.

In mongo there are two collections, Accounts and Users. Users belong to their parent Account. I don't want to go the embedded document route in this case, so each User document will have an AccountID in it to link the user back to their parent Account.

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

My current entities in .net are:

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将它们映射到模型

Those are then mapped to models using AutoMapper in the controller

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; }

}

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

And an example of a controller method where the mapper is used:

[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");
        }


    }

一切正常.我可以调用控制器方法,获取数据,然后将其从实体映射到模型,然后从控制器方法返回.

All that works just fine. I can call the controller methods, get the data, and it gets mapped from entity to model and then returned from the controller method.

问题是这样的:我想返回用户数据以及该帐户的信息(例如:帐户名).所以只是一个简单的连接.

The issue is this: I'd like to return the user data with information from the account (example: account name). So just a simple join.

我认为我可以使用此

I think I have an handle on how to do the join itself, using one of the methods outlined in this answer. But my question is, is there a best practice on how to set up my entities and models to make storing this as clean as possible?

我当时正在考虑向用户实体添加属性以存储相关帐户.带有[BsonIgnore]属性标记,因此它不会进入数据库.

I was thinking of adding a property to the User entity to store the related account. Tagged with the [BsonIgnore] attribute so that it stays out of the db.

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

属性

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

仍将保留在用户实体中,因此保留引用.

would still remain in the user entity, so the reference is preserved.

然后,用户模型可以具有

Then, the User model could have properties like

 public string AccountName { get; set; }

使用映射器填充它们.

当您要引用相关对象而不是将其嵌入时,这是设置此方法的最佳方法吗?我想念的这里有些陷阱吗?

Is this the best way to set this up when you want to reference related objects rather then embed them? Is there some gotcha here I'm missing?

推荐答案

看看下面的代码.它使用了我的库 MongoDB.Entities ,该库内置了对一对一的支持实体之间的一对一和多对多关系.

have a look at the code below. it uses my library MongoDB.Entities which has built-in support for one-to-one, one-to-many and many-to-many relationships between 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();
        }
    }
}

这篇关于在.net Core中对mongodb存储的引用关系进行建模的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆