我有以下型号:
public class Student
{
public ObjectId Id { get; set; }
public string Name { get; set; }
}
我控制器中的这个端点:
public IEnumerable<Student> GetAll()
{
MongoCollection<Student> collection = Db.GetCollection<Student>("students");
List<Student> students = collection.AsQueryable().ToList();
return students;
}
公开的GetAll()端点返回一个具有ObjectId类型Id的Student,它不是标准类型。我宁愿希望它是字符串类型。
但是如果我把它改成字符串,我就不能使用.ToList(),得到如下错误:
&#34;无法从BsonType ObjectId反序列化字符串&#34;
我知道我可以使用一些投影和转换来解决这个问题,但是它们会为CRUD方法添加一些丑陋和嘈杂的代码。
将 ID保存在字符串类型中的最佳方法是向公众公开,并且仍然可以使用c#driver的api?
答案 0 :(得分:2)
控制器应该进行转换。通常,控制器应使用DTO与外界进行通信:
public IEnumerable<StudentReadDTO> GetAll()
{
MongoCollection<Student> collection = Db.GetCollection<Student>("students");
List<Student> students = collection.AsQueryable().ToList();
return students.Select(p => AutoMapper.Mapper.DynamicMap<StudentReadDTO>(p));
}
// this DTO should be used for POST and PUT (i.e where there is no id or the id
// is part of the URL) - after all, it doesn't make sense to send the id from the
// client to the server
public class StudentDTO
{
public string Name { get; set; }
}
// this should be used by reading operations, where the id is read from the server
// inheritance in DTOs is a source of confusion and can be painful, but this trivial
// type of inheritance will be fine
public class StudentReadDTO : StudentDTO
{
public string Id { get; set; }
}
此示例使用AutoMapper在Student
和StudentDTO
之间执行基于约定的映射,但如果您愿意,可以自己进行映射。
在数据库层中,由于its properties.
,使用ObjectId
是有意义的
答案 1 :(得分:1)
虽然@mnemosyn使用AutoMapper的建议答案看起来像一个很好的解决方案和一个很好的模式来处理这种情况,但在MongoDB C#驱动程序的情况下,你有一个专用的解决方案,可以简单地把以下属性和你完成了:
public class Student
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Name { get; set; }
}
(我从MongoDB的google group得到了这个解决方案)