使用c#driver

时间:2016-03-30 11:27:34

标签: c# mongodb linq mongodb-query mongodb-.net-driver

我对mongodb相当新,我正在尝试使用byte属性查询集合,但是我收到了一个无效的强制转换异常。总结一下,

public class MongoDbAddressCollection    
{
     private IMongoCollection<Addresses> collection = database.GetCollection<Addresses>("AddressCollection");
     public IEnumerable<Addresses> Where(System.Linq.Expressions.Expression<Func<Addresses, bool>> filter = null)
     {
         var items = collection.AsQueryable().Where(filter);
         if (items == null)
             return null;
         return items.ToList();
     }
}

public class Test
{
    public void DoSomthingWithAddresses()
    {
         MongoDbAddressCollection addressCollection=new MongoDbAddressCollection();
         //exception occurs in MongoDbAddressCollection.Where method when executing the ToList().
         List<Addresses> homeAddresses=addressCollection.Where(x=>x.AddressType==(byte)EnumAddressType.HomeAddress);
         foreach(var address in homeAddresses)
         {
            //do stuff
         }
    }
}

地址实体如下所示

public class Address
{
    public Guid UserId { get; set; }
    public string Street { get; set; }
    public byte AddressType { get; set; }
    .....
}

public enum EnumAddressType
{
    HomeAddress=1,
    WorkAddress=2
}

实际上问题似乎是mongodb和.net之间的类型不匹配,我可以看到WorkAddress实体的AddressType是10,它是2的二进制表示。但是,我想不出除了改变所有字节属性之外的解决方案在我将所有实体插入到集合之前将它们插入到集合中(我们在不同的实体中有很多字节属性)...或者可以通过查询中的变通方法(linq where condition)来解决这个问题吗?

先谢谢。

1 个答案:

答案 0 :(得分:1)

byte类型的序列化确实存在问题。我认为最快的解决方案是将AddressType属性的类型从byte更改为EnumAddressType

public class Address
{
    public Guid UserId { get; set; }
    public string Street { get; set; }
    public EnumAddressType AddressType { get; set; }
}

编写过滤器而不进行强制转换:

var filter = Builders<Address>.Filter
    .Where(x => x.AddressType == EnumAddressType.HomeAddress);

您可以使用以下方法测试过滤器:

public static BsonDocument RenderToBsonDocument<T>(FilterDefinition<T> filter)
{
    var serializerRegistry = BsonSerializer.SerializerRegistry;
    var documentSerializer = serializerRegistry.GetSerializer<T>();
    return filter.Render(documentSerializer, serializerRegistry);
}

结果

var json = RenderToBsonDocument(filter).ToJson();
// Result: { "AddressType" : 1 }

作为替代方法,您可以编写自定义字节序列化程序并使用以下命令进行注册:

BsonClassMap.RegisterClassMap<Address>(cm =>
{
    cm.AutoMap();
    cm.GetMemberMap(c => c.AddressType).SetSerializer(MyCustomByteSerializer.Instance);
});

您可以在此处看到sample serializer code