进出口工作在使用.NET剃刀和MongoDB的项目。 我愿做这样的事情:
@{
var feeds = DP.Database.GetCollection("feeds").FindAll();
}
<ul>
@foreach (dynamic feed in feeds)
{
<li>@feed.message - @feed.from.name</li>
}
</ul>
然而,BsonDocument目前MongoDB的C#驱动程序的FindAll()返回的集合不支持动态对象。 任何人都知道一个.NET 4的动态支持MongoDB的C#的驱动程序?
非常感谢
目前,在MongoDB的动态驱动不支持。 这是因为它是基于.NET 3.5。 然而,由于.NET 4.0组件可引用.NET 3.5组件,可以让你在.NET 4.0中写一个IBsonSerializationProvider和IBsonSerializer支持力度。
我们,10gen的,期待在未来这样做。 我已经飙升在一些支持https://github.com/craiggwilson/mongo-csharp-driver/tree/dynamic如果你想看看。 有最绝对的错误,但它表明这是可能的。
我创建了一个直向前延伸到MongoDB的驱动程序,重新使用序列化的Json.NET文档BSON和反序列化的动态。 通过包括下面的类,你可以简单地转换您的MongoDB查询动态像这样
dynamic obj = collection.FindOneByIdAs<BsonDocument>(someObjectId).ToDynamic();
扩展类:
public static class MongoDynamic
{
private static System.Text.RegularExpressions.Regex objectIdReplace = new System.Text.RegularExpressions.Regex(@"ObjectId\((.[a-f0-9]{24}.)\)", System.Text.RegularExpressions.RegexOptions.Compiled);
/// <summary>
/// deserializes this bson doc to a .net dynamic object
/// </summary>
/// <param name="bson">bson doc to convert to dynamic</param>
public static dynamic ToDynamic(this BsonDocument bson)
{
var json = objectIdReplace.Replace(bson.ToJson(), (s) => s.Groups[1].Value);
return Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
}
}
一定要参考Newtonsoft.Json.dll( http://james.newtonking.com/projects/json-net.aspx )
我使用自定义IBsonSerializer和Newtonsoft.Json一个干净的解决方案。
在BsonClassMap设置你的自定义序列
map.MapProperty(member => member.Data)
.SetElementName("Data")
.SetSerializer(new DynamicSerializer());
或对物业
[BsonSerializer(typeof(DynamicSerializer))]
public dynamic Data { get; set; }
而就包括下面的类
public class DynamicSerializer : IBsonSerializer
{
#region Implementation of IBsonSerializer
public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
{
return Deserialize(bsonReader, nominalType, null, options);
}
public object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType,
IBsonSerializationOptions options)
{
if (bsonReader.GetCurrentBsonType() != BsonType.Document) throw new Exception("Not document");
var bsonDocument = BsonSerializer.Deserialize(bsonReader, typeof(BsonDocument), options) as BsonDocument;
return JsonConvert.DeserializeObject<dynamic>(bsonDocument.ToJson());
}
public IBsonSerializationOptions GetDefaultSerializationOptions()
{
return new DocumentSerializationOptions();
}
public void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
{
var json = (value == null) ? "{}": JsonConvert.SerializeObject(value);
BsonDocument document = BsonDocument.Parse(json);
BsonSerializer.Serialize(bsonWriter, typeof(BsonDocument), document,options);
}
#endregion
}
InfoSlips - GlobalKinetic
只是建立在马克西米利安的答案。 这会从任何查询返回的动态列表。
/// <summary>
/// deserializes this BsonDocument cursor result to a list of .net dynamic objects
/// </summary>
/// <param name="cursor">cursor result to convert to dynamic</param>
/// <returns></returns>
public static List<dynamic> ToDynamicList(this MongoCursor<BsonDocument> cursor)
{
var dynamicList = new List<dynamic>();
var list = cursor.ToList();
for (int i = 0, l = list.Count; i < l; i++)
dynamicList.Add(list[i].ToDynamic());
return dynamicList;
}
尽管这是一个老话题了还是一样适用于今天作出后时一样,我还没有看到它提供了双向支持简单的解决方案在那里的任何解决方案,我已经修改@Maximilian舍雷尔代码,以便它可以让您转换为动态对象这就容易让你再次保存文档。
public static class MongoDynamic
{
/// <summary>
/// deserializes this bson doc to a .net dynamic object
/// </summary>
/// <param name="bson">bson doc to convert to dynamic</param>
public static dynamic ToDynamic(this BsonDocument bson)
{
var json = bson.ToJson(new MongoDB.Bson.IO.JsonWriterSettings { OutputMode = JsonOutputMode.Strict });
dynamic e = Newtonsoft.Json.JsonConvert.DeserializeObject<ExpandoObject>(json);
BsonValue id;
if (bson.TryGetValue("_id", out id))
{
// Lets set _id again so that its possible to save document.
e._id = new ObjectId(id.ToString());
}
return e;
}
}
使用示例:
// Get BsonDocument from db here
BsonDocument doc = ...
// Convert to dynamic.
var d = doc.ToDynamic();
// Lets add a none existant property.
d.Name = "test";
// Assuming you already have your collection set up
collection.Save(new BsonDocument(d));