保存/读取后错误的文档ID

问题描述 投票:0回答:1

在ASP.NET核心应用程序(使用MongoDb)中,我正在尝试检索之前创建的文档。

这是我的文件(POCO):

public class Person
{
    [BsonId]
    public ObjectId Id { get; }

    public string Name { get; set; }

    public Person()
    {
        this.Id = ObjectId.GenerateNewId();
    }
}

我的ASP.NET核心控制器:

public class HomeController : Controller
{
    private readonly IMongoDbContext _context;

    public HomeController(IMongoDbContext context)
    {
        _context = context;
    }

    public async Task<IActionResult> Index()
    {
        var repository = new Repository(_context);

        var personX = await repository.CreatePersonAsync(name: "John created at " + DateTime.Now.ToFileTimeUtc());

        var personY = await repository.GetPersonByIdAsync(personX.Id);

        return View();
    }
}

最后在我的存储库类中:

   public async Task<Person> CreatePersonAsync(string name)
    {
        var person = new Person() { Name = name };

        var filter = Builders<Person>.Filter.Eq("_id", person.Id);

        var saveResult = await this.PersonCollection.ReplaceOneAsync(filter, person, new UpdateOptions { IsUpsert = true });

        return person;
    }

    public async Task<Person> GetPersonByIdAsync(ObjectId id)
    {
        var person = await this.PersonCollection.Find(x => x.Id.Equals(id)).FirstOrDefaultAsync();

        return person;
    }

在Visual Studio 2017 CE中调试我的应用程序时:

  1. personX:Id = {5a3b81ceff702421e00c5c7e},Name =“John创建于131583228941663577”
  2. personY:Id = {5a3b81ceff702421e00c5c7f},Name =“John创建于131583228941663577”

虽然Name值相同,但Ids略有不同。为什么?我错过了什么?

这可能与async / await有关,我搞砸了,因为如果我同步完成所有事情,一切正常。

谢谢你的帮助,伙计们!

ASP.NET Core 2,MongoDb.Driver 2.5

mongodb asp.net-core mongodb-.net-driver
1个回答
2
投票

问题在于你的Person课程。 Id属性没有setter,它只是在构造函数中初始化,值为ObjectId.GenerateNewId()。这就是为什么当调用GetPersonByIdAsync()时,MongoDB驱动程序无法使用存储在数据库中的值填充Id属性,并且填充了使用ObjectId.GenerateNewId()生成的新id。

要解决此问题,请向Id属性添加公共setter。我还建议不要在构造函数中填写它。在创建新的Person实例以添加到数据库时,只需填写它:

public class Person
{
    [BsonId]
    public ObjectId Id { get; set; }

    public string Name { get; set; }
}

public async Task<Person> CreatePersonAsync(string name)
{
    var person = new Person()
    {
        Id = ObjectId.GenerateNewId(),
        Name = name,
    };

    var filter = Builders<Person>.Filter.Eq("_id", person.Id);

    var saveResult = await this.PersonCollection.ReplaceOneAsync(filter, person, new UpdateOptions { IsUpsert = true });

    return person;
}
© www.soinside.com 2019 - 2024. All rights reserved.