当前位置: 首页 > 编程语言 > C#

MongoDBcompositekey-InvalidOperationException-{document}.Identityisnotsupported

时间:2023-04-11 10:39:21 C#

MongoDBcompositekey:InvalidOperationException:{document}.Identityisnotsupported我遇到了一个问题,就是一个复合ID类,它在turn有一个基类,我得到的错误是InvalidOperationException:{document}.Identityisnotsupported。我试图写入数据库的类如下:publicclassProduct:IEntity{publicreadonlySkuSku;公共字符串名称{得到;私有集;}公共字符串描述{得到;私有集;}publicboolIsArchived{得到;私有集;}publicIdentityIdentity=>Sku;publicProduct(Skusku,stringname,boolisArchived){Sku=sku;名字=名字;IsArchived=isArchived;}}publicinterfaceIEntity{IdentityIdentity{get;}}依次有一个IDSku,它是一个由以下复合值(VendorId和VendorId的本地值)组成的类:publicclassSku:Identity{publicreadonlyVendorIdVendorId;公共只读字符串值;publicSku(VendorIdvendorId,stringvalue){VendorId=vendorId;价值=价值;}protectedoverrideIEnumerableGetIdentityComponents(){返回新的object[]{VendorId,Value};}}publicclassVendorId:Identity{publicreadonlystringValue;publicVendorId(stringvalue){值=值;}protectedoverrideIEnumerableGetIdentityComponents(){returnnewobject[]{Value};我有一个我在DDD库中使用的实体身份的基类,基本上这里ToString()输出可以用作ID,如果这样可以简化事情:publicabstractclassIdentity:IEquatable{publicoverrideboolEquals(objectobj){/*snip*/}publicboolEquals(Identityother){/*snip*/}publicoverrideintGetHashCode(){/*snip*/}publicoverridestringToString(){varid=字符串.空;foreach(varcomponentinGetIdentityComponents()){if(string.IsNullOrEmpty(id))id=component.ToString();//第一项,不要添加分隔符elseid+="."+组件;}返回编号;}受保护的抽象IEnumerableGetIdentityComponents();我在应用程序启动时注册了映射://通过匹配的构造函数重新调整只读属性//https://stackoverflow.com/questions/39604820/serialize-仅获取属性on-mongodbConventionRegistry.Register(nameof(ImmutablePocoConvention),newConventionPack{newImmutablePocoConvention()},_=>true);BsonClassMap.RegisterClassMap(cm=>{cm.AutoMap();cm.MapIdMember(c=>c.Sku);});BsonClassMap.RegisterClassMap(cm=>{cm.AutoMap();cm.MapIdMember(c=>c.Id);});但是当我去写的时候,我得到了InvalidOperationException:{document}.Identityisnotsupported。//我的存储方法publicvoidUpsert(Tentity)whereT:IEntity{this.Database.GetCollection(product.GetType().FullName)().ReplaceOneAsync(x=>x.Identity.Equals(entity.Identity),实体,新的UpdateOptions(){IsUpsert=true}).Wait();}varproduct=newProduct(newSku(newVendorId("dell"),"12434"),"RAM",false);myProductRepo.Upsert(产品);不确定这是否过于复杂,因为我直接从我的实体层持久化(或者如果我只是使用Automator和更简单的POCO)...或者我是否缺少一些映射说明感谢您的帮助或指点。我正在通过构造函数帖子查看水合作用,这是通过GetProperties完成的。所以公共只读SkuSku;不会通过classMap.ClassType.GetTypeInfo().GetProperties(_bindingFlags)因为它只能作为成员字段访问。可以改成publicSkuSku{get;因此它更改所有只读字段(Sku-VendorId、Value和VendorId-Value字段)以通过GetPropertieswaterSku-VendorId、Value通过构造函数获得属性获取方法。您还添加cm.MapProperty(c=>c.Identity)所以当用作表达式时,x=>x.Identity.Equals(entity.Identity)可以被序列化为身份不能被水合并且通过ImmutablePocoConventionRegister因为它不是自动映射逻辑运行时的构造函数arg。代码更改:publicclassSku:Identity{publicVendorIdVendorId{get;}公共字符串值{得到;}}publicclassVendorId:Identity{publicstringValue{get;}}BsonClassMap.RegisterClassMap(cm=>{cm.AutoMap();cm.MapIdMember(c=>c.Sku);cm.MapProperty(c=>c.Identity);});这是我使用的代码:}publicProductGetBySku(Skusku){varcollection=ProductsMongoDatabase.Instance.GetCollection();返回collection.Find(x=>x.Sku.Equals(sku)).First();}publicvoidSaveAll(IEnumerableproducts){foreach(varproductinproducts){Save(product);}}publicvoidSave(Productproduct){varcollection=ProductsMongoDatabase.Instance.GetCollection();集合.ReplaceOneAsync(x=>x.Sku.Equals(product.Sku),product,newUpdateOptions(){IsUpsert=true}).Wait();}}在这里设置投影并通过构造该函数支持只读字段,对于更复杂的场景和手动POCO映射,我们可以使用BsonSerializer.RegisterSerializer(typeof(DomainEntityClass),newCustomerSerializer());公共密封类ProductsMongoDatabase:MongoDatabase{privatestaticvolatileProductsMongoDatabase实例;私有静态只读对象SyncRoot=newObject();privateProductsMongoDatabase(){BsonClassMap.RegisterClassMap(cm=>{cm.MapField(c=>c.VendorId);cm.MapField(c=>c.SkuValue);cm.MapCreator(c=>newSku(newVendorId(c.VendorId.VendorShortname),c.SkuValue));});BsonClassMap.RegisterClassMap(cm=>{cm.MapField(c=>c.VendorShortname);cm.MapCreator(c=>newVendorId(c.VendorShortname));});BsonClassMap.RegisterClassMap(cm=>{cm.AutoMap();cm.MapIdMember(c=>c.Sku);cm.MapCreator(c=>newProduct(c.Sku,c.Name,c.IsArchived));});BsonClassMap.RegisterClassMap(cm=>{cm.AutoMap();cm.MapIdMember(c=>c.Id);cm.MapCreator(c=>newVendor(c.Id,c.Name));});}publicstaticProductsMongoDatabase中instance{get{if(instance!=null)返回实例;锁(SyncRoot){如果(实例==null)实例=newProductsMongoDatabase();}返回实例;}}}上面的实现(单例)是从下面的基础派生出来的(任何查询或写入都在父实现中完成):publicabstractclassMongoDatabase{privatereadonlyIConfigurationRepository_configuration;私有只读IMongoClient客户端;私有只读IMongoDatabase数据库;protectedMongoDatabase(){//_configuration=配置;varconnection="mongodb://host:27017";变种数据库=“测试”;this.Client=newMongoClient();this.Database=this.Client.GetDatabase(数据库);}公共列表GetEntityList(){返回GetCollection()。Find(newBsonDocument()).ToList();}publicIMongoCollectionGetCollection(){returnthis.Database.GetCollection(typeof(T).FullName);}}我的Sku领域模型:publicclassSku:Identity{publicreadonlyVendorIdVendorId;公共只读字符串SkuValue;publicSku(VendorIdvendorId,stringskuValue){VendorId=vendorId;skuValue=skuValue;}protectedoverrideIEnumerableGetIdentityComponents(){returnnewobject[]{VendorId,SkuValue};我的产品域模型:publicclassProduct:IEntity{publicreadonlySkuSku;公共字符串名称{得到;私有集;}publicboolIsArchived{得到;私有集;}publicProduct(Skusku,stringname,boolisArchived){Sku=sku;名字=名字;IsArchived=isArchived;}publicvoidUpdateName(stringname){Name=name;}publicvoidUpdateDescription(stringdescription){Description=description;}publicvoidArchive(){IsArchived=true;}publicvoidRestore(){IsArchived=false;}//这是我的框架使用的,不是MongoDBpublicIdentityIdentity=>Sku;}我的VendorID:publicclassVendorId:Identity{publicreadonlystringVendorShortname;publicVendorId(stringvendorShortname){VendorShortname=vendorShortname;}protectedoverrideIEnumerableGetIdentityComponents(){returnnewobject[]{VendorShortname};}}然后我有我的Entity和Identity类型:以上是C#Tutorial:MongoDBCompositeKey:InvalidOperationException:{document}.Identityisnotsupported所有内容分享,如果对大家有用需要进一步了解C#Tutorial,希望大家多多关注——publicinterfaceIEntity{IdentityIdentity{get;}}publicabstractclassIdentity:IEquatable>{privateconststringIdentityComponentDivider=".";publicoverrideboolEquals(objectobj){if(ReferenceEquals(this,obj))returntrue;如果(ReferenceEquals(null,obj))返回false;如果(GetType()!=obj.GetType())返回false;varother=obj作为身份;返回其他!=null&&GetIdentityComponents()。序列相等(其他。GetIdentityComponents());}publicoverridestringToString(){varid=string.Empty;foreach(varcomponentinGetIdentityComponents()){if(string.IsNullOrEmpty(id))id=component.ToString();//第一项,不要添加分隔符elseid+=IdentityComponentDivider+component;}返回编号;}受保护的抽象IEnumerableGetIdentityComponents();公共覆盖intGetHashCode(){返回HashCodeHelper.CombineHashCodes(GetIdentityComponents());}publicboolEquals(Identityother){returnEquals(otherasobject);}}本文收集自网络,不代表立场。如涉及侵权请点击维权联系管理员删除如需转载请注明出处:

最新推荐
猜你喜欢