C# MongoDb自定义集合序列化程序
我有四节简单的课C# MongoDb自定义集合序列化程序,c#,mongodb,serialization,C#,Mongodb,Serialization,我有四节简单的课 public class Zoo{ public ObjectId Id { get; set; } public List<Animal> Animals { get; set; } } public class Animal{ public ObjectId Id { get; set; } public string Name { get; set; } } public class Tiger : Animal{
public class Zoo{
public ObjectId Id { get; set; }
public List<Animal> Animals { get; set; }
}
public class Animal{
public ObjectId Id { get; set; }
public string Name { get; set; }
}
public class Tiger : Animal{
public double Height { get; set; }
}
public class Zebra : Animal{
public long StripesAmount { get; set; }
}
公共类动物园{
公共对象Id{get;set;}
公共列表动物{get;set;}
}
公营动物{
公共对象Id{get;set;}
公共字符串名称{get;set;}
}
公营老虎:动物{
公共双倍高度{get;set;}
}
公共级斑马:动物{
公共长条带装入{get;set;}
}
我已经创建了自定义序列化程序,它允许我将动物对象存储在不同的集合(“动物”)中
class MyAnimalSerializer:SerializerBase
{
public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext,MongoDB.Bson.Serialization.BsonSerializationArgs args,动物值)
{
context.Writer.WriteStartDocument();
context.Writer.WriteName(“\u id”);
context.Writer.WriteObjectId(ObjectId.generateWid());
context.Writer.WriteName(“\t”);
context.Writer.WriteString(value.GetType().Name);
context.Writer.WriteName(“名称”);
context.Writer.WriteString(value.Name);
开关(value.AnimalType)
{
案例动物类型。老虎:
context.Writer.WriteName(“高度”);
context.Writer.WriteDouble((值为Tiger.Height);
打破
案例动物类型。斑马:
context.Writer.WriteName(“StripesAmount”);
context.Writer.WriteInt32((值为Zebra.StripesAmount);
打破
违约:
打破
}
context.Writer.WriteEndDocument();
}
public override Animal反序列化(MongoDB.Bson.Serialization.BsonDeserializationContext,MongoDB.Bson.Serialization.BsonDeserializationArgs args)
{
context.Reader.ReadStartDocument();
ObjectId=context.Reader.ReadObjectId();
string object_type=context.Reader.ReadString();
string animal_name=context.Reader.ReadString();
开关(对象类型)
{
“老虎”案:
double tiger_height=context.Reader.ReadDouble();
context.Reader.ReadEndDocument();
返回新老虎()
{
Id=Id,
名称=动物名称,
高度=老虎的高度
};
违约:
长斑马线=context.Reader.ReadInt64();
context.Reader.ReadEndDocument();
返回新斑马()
{
Id=Id,
名称=动物名称,
条纹安装=斑马纹
};
}
返回null;
}
}
它工作得很好,也允许我这样做:
MongoDB.Bson.Serialization.BsonSerializer.RegisterSerializer(typeof(Animal), new MyAnimalSerializer());
IMongoCollection<Animal> collection = db.GetCollection<Animal>("animals");
var lst = await collection.Find<Animal>(new BsonDocument()).ToListAsync();
MongoDB.Bson.Serialization.BsonSerializer.RegisterSerializer(typeof(Animal),new MyAnimalSerializer());
IMongoCollection=db.GetCollection(“动物”);
var lst=await collection.Find(new BsonDocument()).toListSync();
但是当动物被存放在动物园时,我不能做同样的事情
无法从动物园集合反序列化动物园:
IMongoCollection<Zoo> collection = db.GetCollection<Zoo>("zoocollection");
var lst = await collection.Find<Zoo>(new BsonDocument()).ToListAsync(); //not working here
IMongoCollection=db.GetCollection(“zoocollection”);
var lst=await collection.Find(new BsonDocument()).toListSync()//不在这里工作
是否可以为字段创建自定义集合序列化程序?
public List<Animal> Animals { get; set; }
公共列表动物{get;set;}
有人能举个例子吗?
提前谢谢 您访问过这个页面吗?也有多态类的例子
下面是我存储对象的示例:
public class Zoo
{
[BsonId]
public ObjectId Id { get; set; }
public List<Animal> Animals { get; set; }
}
[BsonDiscriminator(RootClass = true)]
[BsonKnownTypes(typeof(Tiger), typeof(Zebra))]
public class Animal
{
[BsonId]
public ObjectId Id { get; set; }
public string Name { get; set; }
}
public class Tiger : Animal
{
public double Height { get; set; }
}
public class Zebra : Animal
{
public long StripesAmount { get; set; }
}
public class MongoDocumentsDatabase
{
/// <summary>
/// MongoDB Server
/// </summary>
private readonly MongoClient _client;
/// <summary>
/// Name of database
/// </summary>
private readonly string _databaseName;
public MongoUrl MongoUrl { get; private set; }
/// <summary>
/// Opens connection to MongoDB Server
/// </summary>
public MongoDocumentsDatabase(String connectionString)
{
MongoUrl = MongoUrl.Create(connectionString);
_databaseName = MongoUrl.DatabaseName;
_client = new MongoClient(connectionString);
}
/// <summary>
/// Get database
/// </summary>
public IMongoDatabase Database
{
get { return _client.GetDatabase(_databaseName); }
}
public IMongoCollection<Zoo> Zoo { get { return Database.GetCollection<Zoo>("zoo"); } }
}
class Program
{
static void Main(string[] args)
{
var connectionString =
"mongodb://admin:admin@localhost:27017/testDatabase";
var pr = new Program();
pr.Save(connectionString);
var zoo = pr.Get(connectionString);
foreach (var animal in zoo.Animals)
{
Console.WriteLine(animal.Name + " " + animal.GetType());
}
}
public void Save(string connectionString)
{
var zoo = new Zoo
{
Animals = new List<Animal>
{
new Tiger
{
Height = 1,
Name = "Tiger1"
},
new Zebra
{
Name = "Zebra1",
StripesAmount = 100
}
}
};
var database = new MongoDocumentsDatabase(connectionString);
database.Zoo.InsertOneAsync(zoo).Wait();
}
public Zoo Get(string connectionString)
{
var database = new MongoDocumentsDatabase(connectionString);
var task = database.Zoo.Find(e => true).SingleAsync();
task.Wait();
return task.Result;
}
}
公共类动物园
{
[BsonId]
公共对象Id{get;set;}
公共列表动物{get;set;}
}
[BsonDiscriminator(RootClass=true)]
[BsonKnownTypes(虎型、斑马型))]
公营动物
{
[BsonId]
公共对象Id{get;set;}
公共字符串名称{get;set;}
}
公营老虎:动物
{
公共双倍高度{get;set;}
}
公共级斑马:动物
{
公共长条带装入{get;set;}
}
公共类MongoDocumentsDatabase
{
///
///MongoDB服务器
///
私有只读MongoClient\u客户端;
///
///数据库名称
///
私有只读字符串_databaseName;
public MongoUrl MongoUrl{get;private set;}
///
///打开与MongoDB服务器的连接
///
公共MongoDocumentsDatabase(字符串连接字符串)
{
MongoUrl=MongoUrl.Create(connectionString);
_databaseName=MongoUrl.databaseName;
_客户端=新的MongoClient(connectionString);
}
///
///获取数据库
///
公共数据库
{
获取{return _client.GetDatabase(_databaseName);}
}
公共IMongoCollection动物园{get{return Database.GetCollection(“动物园”);}
}
班级计划
{
静态void Main(字符串[]参数)
{
变量连接字符串=
"mongodb://admin:admin@localhost:27017/testDatabase”;
var pr=新程序();
pr.Save(连接字符串);
var zoo=pr.Get(connectionString);
foreach(动物园里的动物,动物)
{
Console.WriteLine(animal.Name+“”+animal.GetType());
}
}
公共void保存(字符串连接字符串)
{
新动物园
{
动物=新列表
{
新老虎
{
高度=1,
Name=“老虎1”
},
新斑马
{
Name=“Zebra1”,
条带数量=100
}
}
};
var数据库=新的MongoDocumentsDatabase(connectionString);
database.Zoo.InsertOneAsync(Zoo.Wait();
}
公共动物园获取(字符串连接字符串)
{
var数据库=新的MongoDocumentsDatabase(connectionString);
public class Zoo
{
[BsonId]
public ObjectId Id { get; set; }
public List<Animal> Animals { get; set; }
}
[BsonDiscriminator(RootClass = true)]
[BsonKnownTypes(typeof(Tiger), typeof(Zebra))]
public class Animal
{
[BsonId]
public ObjectId Id { get; set; }
public string Name { get; set; }
}
public class Tiger : Animal
{
public double Height { get; set; }
}
public class Zebra : Animal
{
public long StripesAmount { get; set; }
}
public class MongoDocumentsDatabase
{
/// <summary>
/// MongoDB Server
/// </summary>
private readonly MongoClient _client;
/// <summary>
/// Name of database
/// </summary>
private readonly string _databaseName;
public MongoUrl MongoUrl { get; private set; }
/// <summary>
/// Opens connection to MongoDB Server
/// </summary>
public MongoDocumentsDatabase(String connectionString)
{
MongoUrl = MongoUrl.Create(connectionString);
_databaseName = MongoUrl.DatabaseName;
_client = new MongoClient(connectionString);
}
/// <summary>
/// Get database
/// </summary>
public IMongoDatabase Database
{
get { return _client.GetDatabase(_databaseName); }
}
public IMongoCollection<Zoo> Zoo { get { return Database.GetCollection<Zoo>("zoo"); } }
}
class Program
{
static void Main(string[] args)
{
var connectionString =
"mongodb://admin:admin@localhost:27017/testDatabase";
var pr = new Program();
pr.Save(connectionString);
var zoo = pr.Get(connectionString);
foreach (var animal in zoo.Animals)
{
Console.WriteLine(animal.Name + " " + animal.GetType());
}
}
public void Save(string connectionString)
{
var zoo = new Zoo
{
Animals = new List<Animal>
{
new Tiger
{
Height = 1,
Name = "Tiger1"
},
new Zebra
{
Name = "Zebra1",
StripesAmount = 100
}
}
};
var database = new MongoDocumentsDatabase(connectionString);
database.Zoo.InsertOneAsync(zoo).Wait();
}
public Zoo Get(string connectionString)
{
var database = new MongoDocumentsDatabase(connectionString);
var task = database.Zoo.Find(e => true).SingleAsync();
task.Wait();
return task.Result;
}
}
public class MyListAnimalSerializer : SerializerBase<List<Animals>>
{
public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext context, MongoDB.Bson.Serialization.BsonSerializationArgs args, List<Animal> value)
{
context.Writer.WriteStartArray();
foreach (Animal mvnt in value)
{
context.Writer.WriteStartDocument();
switch (mvnt.GetType().Name)
{
case "Tiger":
//your serialization here
break;
case "Zebra":
//your serialization here
break;
default:
break;
}
context.Writer.WriteEndDocument();
}
context.Writer.WriteEndArray();
}
public override List<Animals> Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args)
{
context.Reader.ReadStartArray();
List<Animals> result = new List<Animals>();
while (true)
{
try
{
//this catch block only need to identify the end of the Array
context.Reader.ReadStartDocument();
}
catch (Exception exp)
{
context.Reader.ReadEndArray();
break;
}
var type = context.Reader.ReadString();
var _id = context.Reader.ReadObjectId();
var name = context.Reader.ReadString();
if (type == "Tiger")
{
double tiger_height = context.Reader.ReadDouble();
result.Add(new Tiger()
{
Id = id,
Name = animal_name,
Height = tiger_height
});
}
else
{
long zebra_stripes = context.Reader.ReadInt64();
result.Add(return new Zebra()
{
Id = id,
Name = animal_name,
StripesAmount = zebra_stripes
});
}
context.Reader.ReadEndDocument();
}
return result;
}
}
[BsonSerializer(typeof(MyListAnimalSerializer))]
public List<Animal> Animals { get; set; }
public override List<Animals> Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args)
{
context.Reader.ReadStartArray();
context.Reader.ReadBSonType();
List<Animals> result = new List<Animals>();
while (context.Reader.State != MongoDB.Bson.IO.BsonReaderState.EndOfArray)
{
context.Reader.ReadStartDocument();
var type = context.Reader.ReadString();
var _id = context.Reader.ReadObjectId();
var name = context.Reader.ReadString();
if (type == "Tiger")
{
double tiger_height = context.Reader.ReadDouble();
result.Add(new Tiger()
{
Id = id,
Name = animal_name,
Height = tiger_height
});
}
else
{
long zebra_stripes = context.Reader.ReadInt64();
result.Add(return new Zebra()
{
Id = id,
Name = animal_name,
StripesAmount = zebra_stripes
});
}
context.Reader.ReadEndDocument();
context.Reader.ReadBsonType();
}
context.Reader.ReadEndArray();
return result;
}