簡體   English   中英

使用 c# 驅動程序在 mongodb 中針對字節屬性查詢集合

[英]querying a collection against a byte property in mongodb with c# 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 的二進制表示。但是,除了更改所有字節屬性之外,我想不出其他解決方案在我將它們插入到集合之前,我們的實體到 int(我們在不同的實體中有很多字節屬性)......或者可以通過查詢中的解決方法來解決這個問題(linq where 條件)?

提前致謝。

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);
});

您可以在此處查看示例序列化程序代碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM