C\#Mongo 기반 의 공식 드라이버 가 Super 간이 판 MongoDB-ORM 프레임 워 크 를 훑 었 습 니 다.

16480 단어 C#MongoDBORM프레임
문제 대로 GitHub 에서 MongoDB 를 찾 으 려 는 ORM 프레임 을 한 바퀴 돌 고 원 하 는 것 을 이 루 지 못 하고 홈 페이지 를 넘 겼 다https://docs.mongodb.com/drivers/csharp/.
문 서 를 보 니 공식 구동 기능 이 상당히 강하 고 업데이트 속도 가 빠르다 는 것 을 알 수 있 었 다.
  
2.3 이후 드라이버 버 전 은 지원 되 었 습 니 다.Net 5,그리고 방법 은 모두 Task 를 지원 합 니 다.async,await 에 맞 춰 사용 할 수 있 습 니 다.또한 Lambda 표현 식 과 표현 식 트 리 공식 도 지원 합 니 다(https://mongodb.github.io/mongo-csharp-driver/2.12/what_is_new/.
  
정부 가 이렇게 강력 한 구동 을 해 야 하 는데 무슨 ORM 구 조 를 찾 습 니까?우 리 는 정부 구동 수 를 바탕 으로 간단 한 판 을 훑 었 습 니 다.먼저 디자인 방향 을 간단하게 말씀 드 리 겠 습 니 다.
요구 1:먼저 대상 실체 기본 클래스 가 있어 야 합 니 다.왜 실체 대상 기본 클래스 를 만 듭 니까?공식 구동 이 지원 하 는 실체 클래스 와 Collection 의 맵 은 id 필드 가 있어 야 하고 데이터베이스 에 대응 하 는'id",그리고 이 필드 는 ObjectIDl 형식 입 니 다.이렇게

 public class Person
    {
        [BsonId]
        [BsonElement("_id")]
        public ObjectId ID { get; set; }
    }
그래서 실체 기본 클래스 를 만 드 는 것 은 모든 실체 클래스 가 이 id 의 불필요 한 코드 를 만 들 지 않도록 하기 위해 서 입 니 다.
요구 2:실체 클래스 와 Collection 을 자동 으로 매 핑 하여 데이터베이스 연결 을 만 듭 니 다.이 부분 은 조금 복잡 합 니 다.우선 집합 이름 을 가 져 오 는 데 사용 할 Attribute 를 사용자 정의 하고 관리 자 를 만들어 자동 매 핑 초기 화 작업 을 수행 해 야 합 니 다.
요구 3:Repository 창고 류 를 실현 합 니 다.간단 한 CRUD 방법 을 제공 합 니 다.이 부분 은 비교적 간단 합 니 다.패 키 징 을 통 해 공식 구동 이 제공 하 는 API 를 직접 호출 하여 CURD 작업 을 실현 합 니 다.
이 루어 지기 전에 공식 드라이버 를 추가 하고 Nuget 에서 MongoDB.Driver 를 검색 해서 설치 하면 됩 니 다.저 는 2.12.3 버 전 을 사용 합 니 다.
첫 번 째 단계:대상 실체 기본 클래스 만 들 기

[DataContract]
    [Serializable]
    [BsonIgnoreExtraElements(Inherited = true)]  // BSON        ,                     。  ,           ,     。                       
    public abstract class MongoEntityBase : IMongoEntityBase<string>
    {
        protected MongoEntityBase()
        {
            DB_ID = ObjectId.GenerateNewId().ToString();  // id     
        }

        [DataMember]     [BsonElement("_id")]
        [BsonRepresentation(BsonType.ObjectId)]  //   ObjectId             ,      [BsonRepresentation(BsonType.ObjectId)]         ID mongo   ObjectId
        public virtual string DB_ID { get; set; }        
    }

    public interface IMongoEntityBase<TKey>
    {
        [BsonId]
        TKey DB_ID { get; set; }
    }
    public interface IMongoEntityBase : IMongoEntityBase<string>
    {
    }
두 번 째 단계:실체 류 와 Collection 의 자동 매 핑 실현;
우 리 는 먼저 Attribute 류 를 만들어 서 실체 류 에 대응 하 는 집합 이름 을 가 져 올 필요 가 있 습 니 다.다음 과 같 습 니 다.

[AttributeUsage(AttributeTargets.Class, Inherited = true)]
    public class CollectionNameAttribute : Attribute
    {
        public CollectionNameAttribute(string name)

        {
            if (string.IsNullOrEmpty(name)) throw new ArgumentException("Empty collectionname not allowed", "name");

            this.Name = name;
        }

        public string Name { get; private set; } //           Collection  
    }
그 다음 에 하나의 관리 자 를 실현 하여 자동 맵,데이터 베이스 연결 에 사용 되 는 자동 맵 을 실현 합 니 다.공식 구동 은 실체 류 의 자동 맵 을 제 공 했 습 니 다.우 리 는 이어서 조금 만 포장 해 야 합 니 다.공식 자동 맵 demo 는 다음 과 같 습 니 다.
   
일부 준비 작업 을 하려 면 설정 파일 에 데이터베이스 연결 설정 을 추가 하여 데이터 베 이 스 를 연결 하 는 데 사용 해 야 합 니 다.
   
다음 에 우리 의 관리 자 를 실현 합 니 다.이 부분 은 핵심 입 니 다.데이터베이스 Collection 과 의 자동 매 핑 을 실현 하고 mongo 연결 을 자동 으로 만 들 었 습 니 다.

internal static class GlobleManage<T>
    {
        private static string _tableName;
        private static string _dateBaseName;
        private static string _mongoServerSettings;
        private static IMongoCollection<T> _mongoCollection;

        public static IMongoCollection<T> MongoCollection
        {
            get => _mongoCollection;

        }
        public static string DateBaseName
        {
            get => _dateBaseName;
        }

        public static string MongoServerSettings
        {
            get => _mongoServerSettings;
        }
        public static string TableName
        {
            get => _tableName;
        }

        static GlobleManage()
        {
            Init();
        }

        private static void Init()
        {
            //        
            string[] parm = ConfigurationManager.ConnectionStrings["MongoServerSettings"].ConnectionString.Split('/');

            _dateBaseName = parm.Last();
            _mongoServerSettings = ConfigurationManager.ConnectionStrings["MongoServerSettings"].ConnectionString.Replace(@"/" + _dateBaseName, ":27017");


            //         Attribute    
            var entitytype = typeof(T);
            var attr = Attribute.GetCustomAttribute(entitytype, typeof(CollectionNameAttribute));
            // Attribute            
            if (attr != null)
            {
                _tableName = ((CollectionNameAttribute)attr).Name;

            }
            else
            {
                //         MongoEntityBase             
                if (typeof(MongoEntityBase).IsAssignableFrom(entitytype))
                {
                    // No attribute found, get the basetype
                    while (!entitytype.BaseType.Equals(typeof(MongoEntityBase)))
                    {
                        entitytype = entitytype.BaseType;
                    }
                }
                _tableName = entitytype.Name;
            }

            //       
            BsonClassMap.RegisterClassMap<T>(cm => cm.AutoMap());

        
            _mongoCollection = new MongoClient(_mongoServerSettings).GetDatabase(_dateBaseName).GetCollection<T>(_tableName);
        }
    }
세 번 째 단계:Repository 창고 류 를 실현 합 니 다.간단 한 CRUD 방법 을 제공 합 니 다.
우선,창고 류 의 일반적인 인 터 페 이 스 를 만 듭 니 다.

public interface IRepository<T> where T : IMongoEntityBase<string>
    {
        IMongoCollection<T> Collection { get; }

        bool Add(T entity);
        bool Delete(T delete, Expression<Func<T, bool>> conditions = null);
        bool Update(T update, Expression<Func<T, bool>> conditions = null);
        List<T> Find(Expression<Func<T, bool>> conditions = null);
범 형 창고 류 는 인 터 페 이 스 를 실현 하고 관리 자 를 통 해 자동 으로 매 핑 된 IMongo Collection 을 가 져 옵 니 다.

public class Repository<T> : IRepository<T> where T : IMongoEntityBase<string>
    {

        private IMongoCollection<T> _mongoCollection = GlobleManage<T>.MongoCollection;
        public IMongoCollection<T> Collection => _mongoCollection;

        public bool Add(T entity)
        {
            try
            {
                _mongoCollection.InsertOne(entity);
                return true;
            }
            catch (Exception)
            {
                throw;
            }

        }
        public bool Delete(T delete, Expression<Func<T, bool>> conditions = null)
        {
            try
            {
                string _id = string.Empty;
                if (conditions == null)
                {
                    foreach (var item in delete.GetType().GetProperties())
                    {
                        if (item.Name == "DB_ID" && item.GetValue(delete) != null)
                        {
                            _id = item.GetValue(delete).ToString();
                            var result = _mongoCollection.DeleteOne(new BsonDocument("_id", BsonValue.Create(new ObjectId(_id))));
                            return result.IsAcknowledged;
                        }
                    }
                }
                var res = _mongoCollection.DeleteOne(conditions);
                return res.IsAcknowledged;
            }
            catch (Exception)
            {
                throw;
            }
        }

        public bool Update(T update, Expression<Func<T, bool>> conditions = null)
        {
            try
            {

                ObjectId _id;
                var options = new ReplaceOptions() { IsUpsert = true };
                if (conditions == null)
                {
                    foreach (var item in update.GetType().GetProperties())
                    {
                        if (item.Name == "DB_ID" && item.GetValue(update) != null)
                        {
                            _id = new ObjectId(item.GetValue(update).ToString());
                            var result = _mongoCollection.ReplaceOne(new BsonDocument("_id", BsonValue.Create(_id)), update, options);
                            return result.IsAcknowledged;
                        }
                    }
                }
                var res = _mongoCollection.ReplaceOne(conditions, update, options);
                return res.IsAcknowledged;
            }
            catch (Exception)
            {

                throw;
            }
        }

        public List<T> Find(Expression<Func<T, bool>> conditions = null)
        {
            try
            {
                if (conditions == null)
                {
                    conditions = t => true;
                }

                return _mongoCollection.Find(conditions).ToList() ?? new List<T>();

            }
            catch (Exception)
            {
                throw;
            }
        }
    }
간이 판 ORM 프레임 워 크 는 기본적으로 완성 되 더 라 도 이 프레임 워 크 를 이용 하여 CRUD 작업 을 완성 합 니 다.
우선,실체 클래스 를 만 들 고 MongoEntityBase 를 계승 합 니 다.

[Serializable]
    public class Person : MongoEntityBase
    {
        [BsonConstructor]
        public Person(string name, int age, string guid, EnumGender gender)
        {

            Name = name;
            Age = age;
            Guid = guid;
            Gender = gender;
        }
        public string Name { get; set; }
        public int Age { get; set; }
        public string Guid { get; set; }
        public EnumGender Gender { get; set; }
        public List<Person> Students { get => students; set => students = value; }
        public Pet Pet { get => pet; set => pet = value; }

        private Pet pet;

        public override string ToString()
        {
            return "DB_ID:" + this.DB_ID + "  " + "user:" + Name + "  " + "age:" + Age + "  " + "guid:" + Guid + "  " + "Gender:" + Gender.ToString() + "  " + "   " + Pet.Name + "," + Pet.Age + "  ";
        }
        private List<Person> students;

    }
    public enum EnumGender
    {
         ,
         
    }

    public class Pet
    {
        private string name;
        private int age;

        public string Name { get => name; set => name = value; }
        public int Age { get => age; set => age = value; }
    }
그리고 창 을 만들어 서 CRUD 기능 을 테스트 해 보 세 요.호출 은 간단 합 니 다.IRepository한 마디 만 필요 합 니 다.IRepository = new Repository();

public partial class Form1 : Form
    {
        private IRepository<Person> _IRepository = new Repository<Person>();
        private Random random = new Random();
        public Form1()
        {
            InitializeComponent();
        }

        //ADD
        private void button1_Click(object sender, EventArgs e)
        {
            Person person = new Person("  ", 8, Guid.NewGuid().ToString(), EnumGender. );
            person.Students = new List<Person>() { new Person("   1", 8, Guid.NewGuid().ToString(), EnumGender. ),
                new Person("   2", 8, Guid.NewGuid().ToString(), EnumGender. )
                ,new Person("   3", 8, Guid.NewGuid().ToString(), EnumGender. )
                ,new Person("   4", 8, Guid.NewGuid().ToString(), EnumGender. )};
            person.Pet = new Pet() { Name = "  ", Age = 3 };
            _IRepository.Add(person);
            richTextBox1.Text += "    !\r
"; } //Find private void button2_Click(object sender, EventArgs e) { var id = textBox1.Text.Trim(); var list = _IRepository.Find(t => t.DB_ID.Equals(id)); richTextBox1.Text += "Find :" + "\r
"; foreach (var item in list) { richTextBox1.Text += item.ToString() + "\r
"; } } //Delete private void button3_Click(object sender, EventArgs e) { var id = textBox1.Text.Trim(); //var res = _IRepository.Delete(t => t.DB_ID.Equals(id)); var rese = _IRepository.Find(t => t.DB_ID.Equals(id)).FirstOrDefault(); var res = _IRepository.Delete(rese); richTextBox1.Text += id + " :" + res;/*res.IsAcknowledged + res.DeletedCount;*/ } //Update private void button4_Click(object sender, EventArgs e) { var guid = textBox1.Text.Trim(); Person person = _IRepository.Find(t => t.DB_ID.Equals(guid)).FirstOrDefault(); person.Name = " " + random.Next(1, 10); var res = _IRepository.Update(person); richTextBox1.Text += guid + " :" + res; } //Clear private void button5_Click(object sender, EventArgs e) { textBox1.Clear(); richTextBox1.Clear(); } //FindAll private void button6_Click(object sender, EventArgs e) { var list = _IRepository.Find(); richTextBox1.Text += "FindAll :" + "\r
"; foreach (var item in list) { richTextBox1.Text += item.ToString() + "\r
"; } } }

간이 버 전의 기능 은 기본적으로 모두 실현 되 었 는데,실제로 성숙 한 ORM 프레임 워 크 는 아직도 해 야 할 일이 많다.
링크:https://pan.baidu.com/s/1t9xbfQXhb6iz5QJeC0WLOQ
추출 코드:y9d 2
이상 은 C\#Mongo 의 공식 드라이버 를 바탕 으로 Super 간이 판 MongoDB-ORM 프레임 워 크 에 대한 상세 한 내용 입 니 다.C\#MongoDB-ORM 프레임 워 크 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기