在.NET 4中是否有mongodb C#驱动程序支持System.Dynamic.DynamicObject?

hoa*_*ang 17 mongodb dynamicobject c#-4.0 mongodb-.net-driver

我正在开发一个使用.NET Razor和mongodb的项目.我想做这样的事情:

@{
    var feeds = DP.Database.GetCollection("feeds").FindAll();
}
<ul>
    @foreach (dynamic feed in feeds)
    {
        <li>@feed.message - @feed.from.name</li>
    }
</ul>
Run Code Online (Sandbox Code Playgroud)

但是,当前的mongodb C#驱动程序FindAll()返回不支持动态对象的BsonDocument集合.有人知道.NET 4动态支持的mongodb C#驱动程序吗?

非常感谢

小智 18

我创建了一个MongoDB驱动程序的直接扩展,它使用Json.NET重新序列化BSON文档并将其反序列化为动态.通过包含以下类,您可以简单地将MongoDB查询转换为动态类似

dynamic obj = collection.FindOneByIdAs<BsonDocument>(someObjectId).ToDynamic();
Run Code Online (Sandbox Code Playgroud)

扩展类:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

一定要参考Newtonsoft.Json.dll(http://james.newtonking.com/projects/json-net.aspx)

  • 使用`bson.ToJson(new JsonWriterSettings {OutputMode = JsonOutputMode.Strict})`不需要所有Regex处理来删除Mongo特定的Json方法. (2认同)

Cra*_*son 14

目前,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上加了一些支持.肯定有很多错误,但它表明它是可能的.

  • 我们仍在研究文档,但我们支持2.0.0驱动程序中的动态(目前在rc0中):http://mongodb.github.io/mongo-csharp-driver/2.0/what_is_new/#new-api (2认同)

Rol*_*els 5

我有一个使用自定义IBsonSerializer和Newtonsoft.Json的干净解决方案.

在BsonClassMap上设置自定义序列化程序

map.MapProperty(member => member.Data)
   .SetElementName("Data")
   .SetSerializer(new DynamicSerializer());
Run Code Online (Sandbox Code Playgroud)

或在酒店

[BsonSerializer(typeof(DynamicSerializer))]
public dynamic Data { get; set; }
Run Code Online (Sandbox Code Playgroud)

并且只包括以下课程

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
}
Run Code Online (Sandbox Code Playgroud)

InfoSlips - GlobalKinetic