,我收到一個錯誤說InvalidOperationException: {document}.Identity is not supported.
MongoDB的複合鍵:InvalidOperationException異常:不支持{}文件.Identity
我試圖寫入到數據庫中的類是如下:
public class Product : IEntity<Product>
{
public readonly Sku Sku;
public string Name { get; private set; }
public string Description { get; private set; }
public bool IsArchived { get; private set; }
public Identity<Product> Identity => Sku;
public Product(Sku sku, string name, bool isArchived)
{
Sku = sku;
Name = name;
IsArchived = isArchived;
}
}
public interface IEntity<T>
{
Identity<T> Identity { get; }
}
反過來具有ID Sku
其低於複合值的形成(VendorId
內Sku
本地Value
和)的類:
public class Sku : Identity<Product>
{
public readonly VendorId VendorId;
public readonly string Value;
public Sku(VendorId vendorId, string value)
{
VendorId = vendorId;
Value = value;
}
protected override IEnumerable<object> GetIdentityComponents()
{
return new object[] {VendorId, Value};
}
}
public class VendorId : Identity<Vendor>
{
public readonly string Value;
public VendorId(string value)
{
Value = value;
}
protected override IEnumerable<object> GetIdentityComponents()
{
return new object[] {Value};
}
}
我有一個基類爲我的實體Identity
,我在我的DDD庫使用,基本上這裏的ToString()輸出可以被用作ID,如果這將簡化事情:
public abstract class Identity<T> : IEquatable<Identity<T>>
{
public override bool Equals(object obj) { /* snip */ }
public bool Equals(Identity<T> other) { /* snip */ }
public override int GetHashCode() { /* snip */ }
public override string ToString()
{
var id = string.Empty;
foreach (var component in GetIdentityComponents())
{
if (string.IsNullOrEmpty(id))
id = component.ToString(); // first item, dont add a divider
else
id += "." + component;
}
return id;
}
protected abstract IEnumerable<object> GetIdentityComponents();
}
我註冊映射的應用開始:
// rehydrate readonly properties via matched constructor
// https://stackoverflow.com/questions/39604820/serialize-get-only-properties-on-mongodb
ConventionRegistry
.Register(nameof(ImmutablePocoConvention), new ConventionPack { new ImmutablePocoConvention() }, _ => true);
BsonClassMap.RegisterClassMap<Product>(cm =>
{
cm.AutoMap();
cm.MapIdMember(c => c.Sku);
});
BsonClassMap.RegisterClassMap<Vendor>(cm =>
{
cm.AutoMap();
cm.MapIdMember(c => c.Id);
});
然而,當我去寫,我得到InvalidOperationException: {document}.Identity is not supported.
// my respositoru method
public void Upsert<T>(T entity) where T : IEntity<T>
{
this.Database
.GetCollection<T>(product.GetType().FullName)()
.ReplaceOneAsync(x=>x.Identity.Equals(entity.Identity), entity, new UpdateOptions() {IsUpsert = true})
.Wait();
}
var product = new Product(new Sku(new VendorId("dell"), "12434"),"RAM", false);
myProductRepo.Upsert(product);
不知道這是否是現在過於由我從複雜,我的實體層堅持直接(或如果我只是使用automapper和簡單的POCO)...或者,如果我錯過了一些映射指令。
欣賞任何幫助或指針。
不知道'toString()'假設在這裏做什麼。你可以添加「實體」對象的職位?我正在通過構造函數post來查看通過'GetProperties'完成的水合作用。所以'public readonly Sku Sku;'不會通過'classMap.ClassType.GetTypeInfo() .GetProperties(_bindingFlags)'bcoz顯示出它只能被成員字段訪問。你可以把它改成公共Sku Sku {get; }'所以它通過'GetProperties'通過構造函數進行水合,並將所有隻讀('Sku - VendorId,Value'&'VendorId - Value'字段)更改爲屬性getter方法。 – Veeram
也不知道爲什麼你有額外的'身份身份=> Sku'字段,可能是你可以改變'ReplaceOneAsync(x => x.Sku.Equals(entity.Sku),實體,新的UpdateOptions(){IsUpsert =真})'。在完成所有提到的更改後,我能夠將複合鍵ID與其他字段序列化。 –
Veeram
感謝Veeram花時間來幫助:)我正在嘗試製作一個通用的存儲庫基類。身份屬性由我的DDD框架的其他部分使用。在代碼中包含了IEntity類型。如果我使它過於複雜的基礎知識庫類,我可以放棄,並堅持使用插入,因爲你所提到的是在每個存儲庫的基礎上工作。 –
g18c