2016-11-30 93 views
1

我正在使用MongoDB在WPF應用程序中存儲數據。我有幾個 '模型' 類,從相同的基本類似這樣的繼承:MongoDB中的默認ObjectId

基地:

public class MongoEntityBase 
{ 
    [BsonId] 
    [BsonIgnoreIfDefault] 
    public ObjectId Id { get; set; } 

    public DateTime DateCreated { get; set; } 
} 

第一數據類:

public class Class1 : MongoEntityBase 
{ 
    public string Description { get; set; } 

    public decimal MaxAmount { get; set; } 
} 

第二類數據:

public class Class2 : MongoEntityBase 
{ 
    public string Code { get; set; } 

    public string Message { get; set; } 
} 

我使用ReplaceAsync和激活的Upsert函數來插入或更新數據。當我插入新的Class1實體時,它正確地存儲在帶有生成的ObjectId的數據庫中,但是當我以相同的方式插入Class2實體時,它與默認的ObjectId(只是零)一起存儲。所以當我插入第二個新文檔時,它只是替換第一個文檔,所以在這個集合中不可能有多個文檔。

你有什麼想法嗎,爲什麼它在一種情況下工作,而不是在其他情況下工作?有什麼建議?

+0

你是否還有其他的東西,或者你在代碼中設置了class2對象的id?我已經嘗試使用以下代碼來精確確定您的示例:\t var coll = db.GetCollection (「Class2」); \t coll.InsertOne(new Class2 {Code =「bla」,Message =「fsdfs」}); \t coll.InsertOne(new Class2 {Code =「bla2」,Message =「fsdfs2」});我有兩個不同的文檔集合 –

+0

我插入文檔由ReplaceOne與Upsert爲真,所以如果它有有效的ID,它應該被更新,如果它是默認或不存在的ID,它應該被插入。 –

+0

如果我用replaceOne插入新項目,他們確實有有效的objectid(class1和class2)。你確定,那個class2項目有默認ID嗎?也許問題在於你在替換什麼,如果你寫了類似ReplaceOne(c => true ....)的東西,你將始終有一個文檔在集合中,而不依賴於id。 –

回答

0

好的,很抱歉,我可能在兩天後發現問題。 因爲守則第一類必須是唯一的,我打電話這種CONSTRUTION:

await _coll.ReplaceOneAsync(m => m.Code == message.Code, message, 
        new UpdateOptions { IsUpsert = true }); 

在這種情況下,我在尋找與「非ID」節點DB和當代碼無法找到,比Mongo創建新文檔並將其替換爲生成的DefaultId。

但與Class1的第二種情況下,我沒有任何獨特的領域,所以我給這個:

await _coll.ReplaceOneAsync(c => c.Id.Equals(code.Id), code, 
        new UpdateOptions {IsUpsert = true}); 

所以我「觸摸」 ID字段和在這種情況下可能蒙戈認爲,這是我想要使用的ID,因此當某個文檔帶有DefaultId時,它將與此DefaultId一起存儲,而不會被生成的ID替換。當第二個文檔帶有Id時,它將被替換。在這種情況下,需要手動生成ID您保存文檔之前是這樣的:

if(entity.Id == ObjectId.Empty) 
    entity.Id = ObjectId.GenerateNewId(); 

這不是我的觀點很清楚,所以我希望這可以幫助的人。