用WPF+MongoDB開發房產資訊收集器(3)——MongoDB入門

來源:互聯網
上載者:User

距離上一篇文字過去已經很久了。一方面是工作有點忙,另外也是遇到點問題,到現在也沒有解決。這個問題我會在文章的結尾在提出來,現在先進入這篇文章的主題吧——MongoDB入門。

由於我完全是一個徹徹底底的初學者,所以寫的都只是非常非常粗淺的入門內容,各位看官不要鄙視~~~~

  • 資料庫安裝
    資料庫的安裝,網上到處都是,我也是Google的,就不哆嗦,這裡上個連結吧。MongoDB 安裝與啟動
    另外,對於初學者來說,我覺得直接用命令列是最好的學習資料庫命令的途徑。但畢竟比較累。這裡也推薦兩個GUI的MongoDB資料庫管理工具。
    1. MongoVUE 這是老外開發的一個工具。
    2. MagicMongoDBTool 這是原子裡的magicDict開發的。各位可以去膜拜下~哈哈。作者已經開源了項目,有興趣的朋友可以下載原始碼自己瞅瞅。

  • 資料庫連接
    在串連資料庫之前,我們首先需要確定我們要用的MongoDB Driver,Driver其實有很多,但我都沒有接觸過,也是初學,就從官方的Driver開始吧。下載編譯之後應該有兩個dll檔案,分別是MongoDB.Bson.dll和MongoDB.Driver.dll。
    下面是我資料庫連接的代碼:
    ///<summary>
    /// 串連資料庫
    ///</summary>
    ///<param name="info"></param>
    public static void Connect(DbInfo info)
    {
    DbHelper.info = info;
    if (info.DbType == DbType.MongoDB)
    {
    MongoServerSettings mss = new MongoServerSettings();
    mss.ConnectionMode = ConnectionMode.Direct; // 資料庫連接模式
    //mss.ConnectionMode = ConnectionMode.ReplicaSet; // 這個是針對資料庫集的(多個資料庫地址)
    mss.ConnectTimeout = new TimeSpan(0, 0, 20); // 逾時時間 20s
    mss.Server = new MongoServerAddress(info.Source, info.Port); // 資料庫
    // mss.Servers是針對資料庫集的

    //mss.DefaultCredentials = new MongoCredentials(info.Uid, info.Pwd, true);
    MongoServer ms = new MongoServer(mss);
    MongoDatabaseSettings mds = new MongoDatabaseSettings(ms, info.DbName);

    ms.Connect();
    db = new MongoDatabase(ms, mds); // 儲存MongoDatabase資訊,以便後續調用
    }
    }

    這樣串連資料庫就OK了。

  • Mapping
    串連好了資料庫,就需要將自己定義的類和資料進行映射了。Driver裡面(MongoDB.Bson.dll)已經提供了相應的映射方法:
    BsonClassMap.RegisterClassMap<T>(cm =>
    {
    cm.AutoMap();
    });

    另外在Mapping的時候也可以直接設定id以及id產生的方法:

    BsonClassMap.RegisterClassMap<T>(cm =>
    {
    cm.AutoMap();
    cm.SetIdMember(cm.GetMemberMap(c => c.ID));
    cm.IdMemberMap.SetIdGenerator(StringObjectIdGenerator.Instance);
    });

    如果不在映射的時候設定,也可以在定義類時為相應的ID欄位添加BsonId的屬性:

    [BsonId(IdGenerator = typeof(StringObjectIdGenerator))]
    public virtual string ID { get; set; }

    通過屬性,也可以設定屬性不映射到資料庫,那樣在讀寫資料庫的時候,該屬性就會被忽略掉:

    [BsonIgnore]
    public string FavImage {get; set;}
  • 增刪改查資料庫
    接下去我們就可以通過Driver讀寫資料庫了。
    在擷取資料之前,我們需要擷取對應類映射的Collection:
    DbHelper.db.GetCollection<T>(name);   // name表示T映射的Collection名稱

    GetCollection這個方法必須指定name參數。其實這裡我覺得之前在映射的時候應該已經確定了T對應的Collection的名稱,為什麼這裡的name必須要指定呢?還是說有其他方法我不知道的?
    MongoDB的讀資料是Find命令。在Driver中也都是Find/FindAll方法。

    GetCollection<T>().FindAll();

    在實際應用在,我們一般都是會有查詢條件,以及排序條件的。
    MongoDB的查詢條件是IMongoQuery,排序條件是IMongoSortBy。

    GetCollection<T>().Find(query).SetSortOrder(sortBy);

    同時你也可以利用SetSkip和SetLimit來進行分頁:

    GetCollection<T>().Find(query).SetSortOrder(sortBy).SetSkip(skip).SetLimit(limit);

    下面的是我根據標籤擷取對應資料的方法,根據更新時間排序,還沒有處理分頁的功能:

    ///<summary>
    /// 擷取標籤對應的資料
    ///</summary>
    ///<param name="ht"></param>
    ///<returns></returns>
    public static List<HouseInfo> Find(HouseTag ht)
    {
    QueryComplete query = null;
    if (ht != null)
    {
    query = Query.And(
    Query.GTE(HouseTag.PNameArea, ht.AreaMin),
    Query.LTE(HouseTag.PNameArea, ht.AreaMax),
    Query.GTE(HouseTag.PNamePrice, ht.PriceMin),
    Query.LTE(HouseTag.PNamePrice, ht.PriceMax),
    Query.GTE(HouseTag.PNamePriceTotal, ht.PriceTotalMin),
    Query.LTE(HouseTag.PNamePriceTotal, ht.PriceTotalMax),
    Query.GTE(HouseTag.PNameYear, ht.YearMin),
    Query.LTE(HouseTag.PNameYear, ht.YearMax)
    );
    if (!string.IsNullOrEmpty(ht.Zone))
    {
    MongoDB.Bson.BsonRegularExpression reg = new MongoDB.Bson.BsonRegularExpression(string.Format("*{0}*", ht.Zone));
    query = Query.And(query, Query.Matches(HouseTag.PNameZone, reg));
    }
    }
    return MongoHelper.FindAll<HouseInfo>(query, SortBy.Descending("UpdateTime")).ToList();
    }

    擷取了資料之後,接下去就是儲存資料了,儲存(新增和修改)資料相對簡單一點,直接用Save就好了,而且,我這裡也沒有處理變化的資料,每次儲存都是整個對象進行了更新(就效率而言,肯定不合適,但就編程而言,那是方便不只一點點啊):

    ///<summary>
    /// 更新資料集合
    ///</summary>
    ///<typeparam name="T"></typeparam>
    ///<param name="listEntity"></param>
    public static void Save<T>(IEnumerable<IMongoEntity> listEntity)
    where T : class, IMongoEntity
    {
    if (listEntity != null)
    {
    MongoCollection<T> col = GetCollection<T>();
    foreach (IMongoEntity entity in listEntity)
    {
    col.Save(entity);
    }
    }
    }

    刪除資料相對更新有個差別是需要根據對應擷取條件(IMongoQuery):

    ///<summary>
    // 刪除資料集合
    ///</summary>
    ///<typeparam name="T"></typeparam>
    ///<param name="listEntity"></param>
    public static void Remove<T>(IEnumerable<IMongoEntity> listEntity)
    where T : class, IMongoEntity
    {
    if (listEntity != null)
    {
    MongoCollection<T> col = GetCollection<T>();
    foreach (IMongoEntity entity in listEntity)
    {
    col.Remove(Query.EQ("ID", entity.ID));
    }
    }
    }

在最後說明下我在文章開頭的時候提到的之前遇到的問題。

是這樣的,我覺得這個房產資訊採集器的目標使用者主要是些關注房產交易資訊的朋友,而這些人總不能都指望他們是IT出身,或者希望他們可以非常順利的自己安裝部署MongoDB吧。所以我就想是否可以在程式啟動並執行時候自己去判斷是否有MongoDB的服務,是否已經啟動了MongoDB資料庫。如果沒有服務的話,建立一個服務;如果沒有啟動的話,就啟動相應的服務。總之只要開啟房產資訊採集器,不需要再做其他的就直接可以用了。可是筆者嘗試了n久,沒能實現建立MongoDB服務的功能。

我的想法是在發布的時候將MongoDB的相應目錄也一起放在程式的根目錄。然後在沒有相應服務的時候,啟動相應的命令列自動建立MongoDB的服務,並啟動。

所以這裡有兩個問題:

  1. 自動建立MongoDB的服務。
  2. 自動運行MongoDB的服務。

這兩個問題,當然也可以引申為建立並啟動服務(包括其他任何服務)。

不知道各位有沒有什麼建議或已經實現的方法?如果有的話,評論、私信都歡迎啊。最好能有現成的代碼。哈哈。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.