初始化IMongoCollection
时,我使用接口作为集合类型。我使用接口类作为集合,以便它可以更好地进行测试。
public IMongoCollection<IEmployee> Employees => Database.GetCollection<IEmployee>("employee");
public interface IEmployee
{
[BsonId]
ObjectId Id { get; set; }
string Name { get; set; }
}
[BsonDiscriminator(Required = true)]
[BsonKnownTypes(typeof(Employee))]
public class Employee : IEmployee
{
public ObjectId { get; set; }
public string Name { get; set; }
}
我有一个Employee
的数据库类,它实现了IEmployee
。存储到数据库时,我必须存储Employee
类型,因为我无法声明IEmployee
的新实例。
var emp = new Employee
{
Id = ObjectId.GenerateNewId();
Name = "Wayne Rooney";
};
// Insert into the Employees collection
await Employees.InsertOneAsync(emp);
当我想要替换/更新该文档时,我无法理解,因为我正在查询IEmployee
的较低层类。
await Employees.FindOneAndReplaceAsync(f => f.Id.ToString() == context.Id, g);
在这种情况下, context
是我传入的Employee
类型的参数。g
是类型Employee
的更新文档。在这种情况下,f
是IEmployee
类型。当我进行替换时,出现[document].Id.ToString() is not supported
错误。
所以问题是,我能够插入和检索它们,但无法更新/替换/删除文档。有什么建议吗?
答案 0 :(得分:0)
首先,几个人抬头。
插入数据库时,如果您已将ObjectId
指定为BsonId
,则无需手动设置。
因此,请在您的ID上设置BsonId
- 属性。
public class Employee : IEmployee
{
[BsonId]
public ObjectId Id { get; set; }
public string Name { get; set; }
}
然后插入:
var emp = new Employee
{
Name = "Wayne Rooney";
};
// Insert into the Employees collection
await Employees.InsertOneAsync(emp);
插入时,将自行设置唯一的ObjectId
。
问题本身很可能在于ToString()
- 你的Linq查询的一部分。我不确定它是否可以很好地转换为mongo-query。快速解决方法就是使用类似的东西:
var id = new ObjectId(context.Id);
await Employees.ReplaceOneAsync(f => f.Id == id, g);
这消除了ToString()
- 调用并直接比较ObjectId
。
Linq查询的支持在驱动程序中有些限制。我建议不要使用它们(这里也有一些开销)。
建议的,最直接的方法是使用内置过滤器。
例如:
var filter = Builders<IEmployee>.Filter
.Eq(nameof(Employee.Id), new ObjectId(context.Id));
await Employees.ReplaceOneAsync(filter, g);
nameof(Employee.Id)
是C#6,将返回"Id"
。如果您不支持C#6,那么只需使用"Id"
即可。