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

时间:2017-12-21 10:02:59

标签: mongodb asp.net-core mongodb-.net-driver

在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 = {5a3b81ceff702421e00c5c7 e },姓名=&#34; John创建于131583228941663577&#34;
  2. personY:Id = {5a3b81ceff702421e00c5c7 f },姓名=&#34; John创建于131583228941663577&#34;
  3. 虽然Name值相同,但Ids略有不同。 为什么?我错过了什么?

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

    感谢您的帮助,伙计们!

    ASP.NET Core 2,MongoDb.Driver 2.5

1 个答案:

答案 0 :(得分:2)

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

要解决此问题,请将公共设置器添加到Id属性。我还建议不要在构造函数中填写它。只需在创建用于添加到数据库的新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;
}