MongoDB;
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;
using System.Web;
namespace MongoHelper.MongoClientService
{
/// <summary>
/// MongoDb基于C#语言操作帮助类
/// </summary>
public class MongoDbCsharpHelper
{
public static MongoClient _client;
private readonly string databaseName =
null;
private MongoDB.Driver.IMongoDatabase database =
null;
private readonly bool autoCreateDb =
false;
private readonly bool autoCreateCollection =
false;
static MongoDbCsharpHelper()
{
BsonDefaults.GuidRepresentation =
GuidRepresentation.Standard;
}
public MongoDbCsharpHelper(
string dbName,
bool autoCreateDb =
false,
bool autoCreateCollection =
false)
{
_client =
new MongoClient();
this.databaseName =
dbName;
this.autoCreateDb =
autoCreateDb;
this.autoCreateCollection =
autoCreateCollection;
}
#region 私有方法
private MongoClient CreateMongoClient()
{
if (_client.Settings.Server.Host !=
"")
//host
{
_client =
new MongoClient(
"");
//mongodb://username:password@host:27017
}
return _client;
}
private MongoDB.Driver.IMongoDatabase GetMongoDatabase()
{
if (database ==
null)
{
var client =
CreateMongoClient();
if (!DatabaseExists(client, databaseName) && !
autoCreateDb)
{
throw new KeyNotFoundException(
"此MongoDB名称不存在:" +
databaseName);
}
database =
CreateMongoClient().GetDatabase(databaseName);
}
return database;
}
private bool DatabaseExists(MongoClient client,
string dbName)
{
try
{
var dbNames = client.ListDatabases().ToList().Select(db => db.GetValue(
"name").AsString);
return dbNames.Contains(dbName);
}
catch //如果连接的账号不能枚举出所有DB会报错,则默认为true
{
return true;
}
}
private bool CollectionExists(IMongoDatabase database,
string collectionName)
{
var options =
new ListCollectionsOptions
{
Filter = Builders<BsonDocument>.Filter.Eq(
"name", collectionName)
};
return database.ListCollections(options).ToEnumerable().Any();
}
private MongoDB.Driver.IMongoCollection<TDoc> GetMongoCollection<TDoc>(
string name, MongoCollectionSettings settings =
null)
{
var mongoDatabase =
GetMongoDatabase();
if (!CollectionExists(mongoDatabase, name) && !
autoCreateCollection)
{
throw new KeyNotFoundException(
"此Collection名称不存在:" +
name);
}
return mongoDatabase.GetCollection<TDoc>
(name, settings);
}
private List<UpdateDefinition<TDoc>> BuildUpdateDefinition<TDoc>(
object doc,
string parent)
{
var updateList =
new List<UpdateDefinition<TDoc>>
();
foreach (
var property
in typeof(TDoc).GetProperties(BindingFlags.Instance |
BindingFlags.Public))
{
var key = parent ==
null ? property.Name :
string.Format(
"{0}.{1}", parent, property.Name);
//非空的复杂类型
if ((property.PropertyType.IsClass || property.PropertyType.IsInterface) && property.PropertyType !=
typeof(
string) && property.GetValue(doc) !=
null)
{
if (
typeof(IList).IsAssignableFrom(property.PropertyType))
{
#region 集合类型
int i =
0;
var subObj =
property.GetValue(doc);
foreach (
var item
in subObj
as IList)
{
if (item.GetType().IsClass ||
item.GetType().IsInterface)
{
updateList.AddRange(BuildUpdateDefinition<TDoc>(doc,
string.Format(
"{0}.{1}", key, i)));
}
else
{
updateList.Add(Builders<TDoc>.Update.Set(
string.Format(
"{0}.{1}", key, i), item));
}
i++
;
}
#endregion
}
else
{
#region 实体类型
//复杂类型,导航属性,类对象和集合对象
var subObj =
property.GetValue(doc);
foreach (
var sub
in property.PropertyType.GetProperties(BindingFlags.Instance |
BindingFlags.Public))
{
updateList.Add(Builders<TDoc>.Update.Set(
string.Format(
"{0}.{1}", key, sub.Name), sub.GetValue(subObj)));
}
#endregion
}
}
else //简单类型
{
updateList.Add(Builders<TDoc>
.Update.Set(key, property.GetValue(doc)));
}
}
return updateList;
}
private void CreateIndex<TDoc>(IMongoCollection<TDoc> col,
string[] indexFields, CreateIndexOptions options =
null)
{
if (indexFields ==
null)
{
return;
}
var indexKeys = Builders<TDoc>
.IndexKeys;
IndexKeysDefinition<TDoc> keys =
null;
if (indexFields.Length >
0)
{
keys = indexKeys.Descending(indexFields[
0]);
}
for (
var i =
1; i < indexFields.Length; i++
)
{
var strIndex =
indexFields[i];
keys =
keys.Descending(strIndex);
}
if (keys !=
null)
{
col.Indexes.CreateOne(keys, options);
}
}
#endregion
public void CreateCollectionIndex<TDoc>(
string collectionName,
string[] indexFields, CreateIndexOptions options =
null)
{
CreateIndex(GetMongoCollection<TDoc>
(collectionName), indexFields, options);
}
public void CreateCollection<TDoc>(
string[] indexFields =
null, CreateIndexOptions options =
null)
{
string collectionName =
typeof(TDoc).Name;
CreateCollection<TDoc>
(collectionName, indexFields, options);
}
public void CreateCollection<TDoc>(
string collectionName,
string[] indexFields =
null, CreateIndexOptions options =
null)
{
var mongoDatabase =
GetMongoDatabase();
mongoDatabase.CreateCollection(collectionName);
CreateIndex(GetMongoCollection<TDoc>
(collectionName), indexFields, options);
}
public List<TDoc> Find<TDoc>(Expression<Func<TDoc,
bool>> filter, FindOptions options =
null)
{
string collectionName =
typeof(TDoc).Name;
return Find<TDoc>
(collectionName, filter, options);
}
public List<TDoc> Find<TDoc>(
string collectionName, Expression<Func<TDoc,
bool>> filter, FindOptions options =
null)
{
try
{
var colleciton = GetMongoCollection<TDoc>
(collectionName);
return colleciton.Find(filter, options).ToList();
}
catch (Exception)
{
throw;
}
}
public List<TDoc> FindByPage<TDoc, TResult>(Expression<Func<TDoc,
bool>> filter, Expression<Func<TDoc, TResult>> keySelector,
int pageIndex,
int pageSize,
out int rsCount)
{
string collectionName =
typeof(TDoc).Name;
return FindByPage<TDoc, TResult>(collectionName, filter, keySelector, pageIndex, pageSize,
out rsCount);
}
public List<TDoc> FindByPage<TDoc, TResult>(
string collectionName, Expression<Func<TDoc,
bool>> filter, Expression<Func<TDoc, TResult>> keySelector,
int pageIndex,
int pageSize,
out int rsCount)
{
var colleciton = GetMongoCollection<TDoc>
(collectionName);
rsCount =
colleciton.AsQueryable().Where(filter).Count();
int pageCount = rsCount / pageSize + ((rsCount % pageSize) >
0 ?
1 :
0);
if (pageIndex > pageCount) pageIndex =
pageCount;
if (pageIndex <=
0) pageIndex =
1;
return colleciton.AsQueryable(
new AggregateOptions { AllowDiskUse =
true }).Where(filter).OrderByDescending(keySelector).Skip((pageIndex -
1) *
pageSize).Take(pageSize).ToList();
}
public void Insert<TDoc>(TDoc doc, InsertOneOptions options =
null)
{
string collectionName =
typeof(TDoc).Name;
Insert<TDoc>
(collectionName, doc, options);
}
public void Insert<TDoc>(
string collectionName, TDoc doc, InsertOneOptions options =
null)
{
var colleciton = GetMongoCollection<TDoc>
(collectionName);
colleciton.InsertOne(doc, options);
}
public void InsertMany<TDoc>(IEnumerable<TDoc> docs, InsertManyOptions options =
null)
{
string collectionName =
typeof(TDoc).Name;
InsertMany<TDoc>
(collectionName, docs, options);
}
public void InsertMany<TDoc>(
string collectionName, IEnumerable<TDoc> docs, InsertManyOptions options =
null)
{
var colleciton = GetMongoCollection<TDoc>
(collectionName);
colleciton.InsertMany(docs, options);
}
public void Update<TDoc>(TDoc doc, Expression<Func<TDoc,
bool>> filter, UpdateOptions options =
null)
{
string collectionName =
typeof(TDoc).Name;
var colleciton = GetMongoCollection<TDoc>
(collectionName);
List<UpdateDefinition<TDoc>> updateList = BuildUpdateDefinition<TDoc>(doc,
null);
colleciton.UpdateOne(filter, Builders<TDoc>
.Update.Combine(updateList), options);
}
public void Update<TDoc>(
string collectionName, TDoc doc, Expression<Func<TDoc,
bool>> filter, UpdateOptions options =
null)
{
var colleciton = GetMongoCollection<TDoc>
(collectionName);
List<UpdateDefinition<TDoc>> updateList = BuildUpdateDefinition<TDoc>(doc,
null);
colleciton.UpdateOne(filter, Builders<TDoc>
.Update.Combine(updateList), options);
}
public void Update<TDoc>(TDoc doc, Expression<Func<TDoc,
bool>> filter, UpdateDefinition<TDoc> updateFields, UpdateOptions options =
null)
{
string collectionName =
typeof(TDoc).Name;
Update<TDoc>
(collectionName, doc, filter, updateFields, options);
}
public void Update<TDoc>(
string collectionName, TDoc doc, Expression<Func<TDoc,
bool>> filter, UpdateDefinition<TDoc> updateFields, UpdateOptions options =
null)
{
var colleciton = GetMongoCollection<TDoc>
(collectionName);
colleciton.UpdateOne(filter, updateFields, options);
}
public void UpdateMany<TDoc>(TDoc doc, Expression<Func<TDoc,
bool>> filter, UpdateOptions options =
null)
{
string collectionName =
typeof(TDoc).Name;
UpdateMany<TDoc>
(collectionName, doc, filter, options);
}
public void UpdateMany<TDoc>(
string collectionName, TDoc doc, Expression<Func<TDoc,
bool>> filter, UpdateOptions options =
null)
{
var colleciton = GetMongoCollection<TDoc>
(collectionName);
List<UpdateDefinition<TDoc>> updateList = BuildUpdateDefinition<TDoc>(doc,
null);
colleciton.UpdateMany(filter, Builders<TDoc>
.Update.Combine(updateList), options);
}
public void Delete<TDoc>(Expression<Func<TDoc,
bool>> filter, DeleteOptions options =
null)
{
string collectionName =
typeof(TDoc).Name;
Delete<TDoc>
(collectionName, filter, options);
}
public void Delete<TDoc>(
string collectionName, Expression<Func<TDoc,
bool>> filter, DeleteOptions options =
null)
{
var colleciton = GetMongoCollection<TDoc>
(collectionName);
colleciton.DeleteOne(filter, options);
}
public void DeleteMany<TDoc>(Expression<Func<TDoc,
bool>> filter, DeleteOptions options =
null)
{
string collectionName =
typeof(TDoc).Name;
DeleteMany<TDoc>
(collectionName, filter, options);
}
public void DeleteMany<TDoc>(
string collectionName, Expression<Func<TDoc,
bool>> filter, DeleteOptions options =
null)
{
var colleciton = GetMongoCollection<TDoc>
(collectionName);
colleciton.DeleteMany(filter, options);
}
public void ClearCollection<TDoc>(
string collectionName)
{
var colleciton = GetMongoCollection<TDoc>
(collectionName);
var inddexs =
colleciton.Indexes.List();
List<IEnumerable<BsonDocument>> docIndexs =
new List<IEnumerable<BsonDocument>>
();
while (inddexs.MoveNext())
{
docIndexs.Add(inddexs.Current);
}
var mongoDatabase =
GetMongoDatabase();
mongoDatabase.DropCollection(collectionName);
if (!
CollectionExists(mongoDatabase, collectionName))
{
CreateCollection<TDoc>
(collectionName);
}
if (docIndexs.Count >
0)
{
colleciton = mongoDatabase.GetCollection<TDoc>
(collectionName);
foreach (
var index
in docIndexs)
{
foreach (IndexKeysDefinition<TDoc> indexItem
in index)
{
try
{
colleciton.Indexes.CreateOne(indexItem);
}
catch
{ }
}
}
}
}
}
}
【C#】MongoDbCsharpHelper
标签:ges readonly val exception new 集合类 list || ons