【翻譯】首個基於NHibernate的應用程式

来源:http://www.cnblogs.com/13yan/archive/2016/07/14/5671072.html
-Advertisement-
Play Games

首個基於NHibernate的應用程式 Your first NHibernate based application 原文地址:http://www.nhforge.org/wikis/howtonh/your-first-nhibernate-based-application.aspx 本文涉 ...


首個基於NHibernate的應用程式

 Your first NHibernate based application

原文地址:http://www.nhforge.org/wikis/howtonh/your-first-nhibernate-based-application.aspx

 

本文涉及到的DEMO下載

 

定義領域模型

 

讓我們開始通過定義一個非常簡單的領域模型。目前它是由一個稱為產品的實體。該產品具有 3 個屬性:名稱、 類別和中止。

 

添加一個文件夾 Domain 到您的解決方案的 FirstSample 項目。到此文件夾中添加一個新類 Product.cs。該代碼是非常簡單,使用自動屬性 (C# 3.0新的特征)

 

namespace FirstSolution.Domain

{

 public class Product

 {

  public string Name { get; set; }

  public string Category { get; set; }

  public bool Discontinued { get; set; }

 }

}

 

現在我們想要能夠持久化相關資料庫中此實體的實例。我們選擇了 NHibernate來完成這一任務。

領域模型中實體的一個實例對應資料庫表中的行。所以我們必須在資料庫中定義實體和相應的表之間的映射。此映射可以是另外定義一個映射文件 (一個xml 文檔) 或裝飾的實體和屬性,可以完成此映射。隨後,我將開始映射文件的定義。

 

譯者的話:裝飾的實體是什麼?目前我們知道除了xml文件映射,還有Fluent NHibernate的Mapping和特性(attribute,類似Java中註解@),裝飾可能是指他們的統稱吧。

 

定義映射

 

創建一個文件夾 Mappings 到 FirstSample 項目中。併在該文件夾中添加一個新的 xml 文檔並命名為 Product.hbm.xml。請註意"hbm"是文件名稱的一部分。這是一項約定,這個約定用於NHibernate 自動識別這個文件為一個映射文件。右鍵此 xml 文件點擊屬性,在生成操作一項定義"嵌入的資源"

 

在 Windows 資源管理器中找到 nhibernate mapping.xsd,它在 NHibernate 的 src 文件夾中,並將其複製到您的 SharedLibs 文件夾中。編輯 xml 映射文件時,在VS菜單中的XML-架構中導入此xsd文檔。VS 然後將智能感知和驗證。

 

回到在 VS 將架構添加到 Product.hbm.xml 文件

 

讓我們從現在開始。每個映射文件都須定義一個 <hibernate-mapping> 根節點。

 

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

       assembly="FirstSolution"

       namespace="FirstSolution.Domain">

  <!-- more mapping info here -->

</hibernate-mapping>

 

在映射文件引用領域模型類時你一定要提供的類的完全限定的名稱(如 FirstSample.Domain.Product , FirstSample)。若要使 xml 不那麼繁瑣,你可以定義程式集名稱和領域模型類的命名空間,到根節點的兩個屬性:assembly 和namespace。它是類似於使用 C# 中的聲明。

 

現在,我們必須先為產品實體定義一個主鍵。技術上我們可以拿產品的名稱屬性作為主鍵,因為此屬性必須定義,並且必須是唯一的。但通常會使用代理鍵代替它成為主鍵。因此我們將添加一個名為Id的屬性到我們的實體。我們使用 Guid 作為 Id 的類型,但也可以是 int 或 long。

 

using System;

 

namespace FirstSolution.Domain

{

 public class Product

 {

  public Guid Id { get; set; }

  public string Name { get; set; }

  public string Category { get; set; }

  public bool Discontinued { get; set; }

 }

}

 

完整的映射文件

 

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

       assembly="FirstSolution"

       namespace="FirstSolution.Domain">

  <class name="Product">

 <id name="Id">

   <generator class="guid" />

 </id>

 <property name="Name" />

 <property name="Category" />

 <property name="Discontinued" />

  </class>

</hibernate-mapping>

 

NHibernate 不會以我們的方式,比如,它定義了很多合理的預設值。所以,如果您不顯式地提供屬性的列名,它將按屬性名去對應列名。或 NHibernate從類的定義中,可以自動推斷的表名或列名。因此我的 xml 映射文件不會被堆滿冗餘信息。有關於映射文件更詳細的解釋請參閱線上文檔。你可以在這裡找到它。

 

你解決方案資源管理器現在應該看起來像這樣 (Domain.cd 包含我們簡單的領域模型類圖)

 

譯者的話:

 

配置 NHibernate

 

我們現在必須告訴 NHibernate 我們想要使用哪個資料庫產品,並提供詳細的鏈接信息,以連接字元串的形式。NHibernate 支持許多資料庫產品 !

 

向 FirstSolution 項目中添加一個新的 xml 文件,並命名為 hibernate.cfg.xml。將其屬性"複製到輸出目錄"設置為"始終複製"。由於我們引用了SQL Server Compact Edition資料庫在first sample項目中,所以輸入以下信息到xml 文件中。

 

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">

  <session-factory>

 <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>

 <property name="dialect">NHibernate.Dialect.MsSqlCeDialect</property>

 <property name="connection.driver_class">NHibernate.Driver.SqlServerCeDriver</property>

 <property name="connection.connection_string">Data Source=FirstSample.sdf</property>

 

 <property name="show_sql">true</property>

  </session-factory>

</hibernate-configuration>

 

使用此配置文件,我們告訴 NHibernate 我們想要使用 MS SQL Server Compact Edition作為我們的目標資料庫和資料庫的名稱是 FirstSample.sdf (= 連接字元串)。我們同時也定義了希望看到NHibernate生成併發送到資料庫的 SQL語句 (在開發過程中調試時強烈推薦啟用此定義)。仔細檢查你的代碼中有沒有錯別字 !

 

添加一個叫FirstSample.sdf的空的資料庫,到 FirstSample 項目 (選擇本地資料庫作為模板)

 

單擊添加並忽略數據集創建嚮導 (就是點擊取消)。

 

譯者的話:我們不一定安裝過MS SQL Server Compact Edition資料庫,我將在Demo中把它替換成SQLite和相應的配置,這樣我們就不需要為了這個快速入門而去專門找一個資料庫了。

 

測試設置

 

是時候來測試我們的安裝了。首先驗證您的 SharedLibs 文件夾中有以下文件

 

您可以找到Microsoft SQL Server Compact Edition在你的程式文件夾中目錄最後 8 個文件。

 

註︰ System.Data.SqlServerCe.dll 位於子文件夾中的桌面。

 

所有其他文件可以在NHibernate 文件夾中找到。

 

在您的測試項目中添加對 FirstSample 項目的引用。另外測試項目引用 NHibernate.dll、 nunit.framework.dllSystm.Data.SqlServerCe.dll (記得要引用位於 SharedLibs 文件夾中的文件 !)。要註意為設置屬性"複製本地"為 true 為 System.Data.SqlServerCe.dll, 因為在預設情況下它設置為 false !

 

譯者的話:現在VS2012以上都有自帶的單元測試項目,也非常好用。所以無需引用nunit.framework.dll,同樣System.Data.SqlServerCe.dll也可以替換成System.Data.Sqlite.dll。

 

在測試項目中添加一個類,命名為 GenerateSchema_Fixture。

 

現在將下麵的代碼添加到 GenerateSchema_Fixture 文件

 

using FirstSolution.Domain;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using NUnit.Framework;
 
namespace FirstSolution.Tests
{
 [TestFixture]
 public class GenerateSchema_Fixture
 {
  [Test]
  public void Can_generate_schema()
  {
   var cfg = new Configuration();
   cfg.Configure();
   cfg.AddAssembly(typeof (Product).Assembly);
   
   new SchemaExport(cfg).Execute(false, true, false, false);
  }
 }
}

 

測試方法的第一行創建 NHibernate 配置類的一個新實例。此類用於配置 NHibernate。在第二行,我們告訴 NHibernate 配置本身。NHibernate 將留心配置信息,因為我們沒在測試方法中提供任何信息。所以 NHibernate 將搜索輸出目錄中的 hibernate.cfg.xml 文件來調用。這正是我們為什麼要在這個文件中這麼設置的原因。

 

在第三行的代碼,我們告訴 NHibernate 它可以發現並包含Product類的程式集的映射信息。它將在嵌入的資源中只找到一個(Product.hbm.xml)這樣的文件。

 

第四行代碼使用NHibernate中 SchemaExport 的工具類,為我們在自動生成資料庫中的架構。

 

註︰ 我們先不用去理解此測試方法中NHibernate 如何工作 , 但應當關註是否正確地安裝。

 

如果你有安裝的 TestDriven.Net 你可以現在只是右鍵點擊裡面的測試方法並選擇"運行 Test(s)"來執行測試。

 

譯者的話:VS2012以上版本的單元測試可以不用TestDriven.Net和NUnit,微軟有自帶的。

 

如果每一件事是好的你應該看到下麵的結果,在輸出視窗

 

譯者的話:

 

如果你有安裝 ReSharper 你可以開始測試通過單擊黃色綠色圓圈的左邊框,選擇運行。

 

其結果是,如下所示

 

譯者的話:原文沒圖,我們還是用VS自帶的吧,如下圖

 

在出現問題時

 

如果你測試失敗,請仔細檢查你的目標目錄,在其中找到下列文件 (即︰ m:dev\projects\FirstSolution\src\FirstSolution.Tests\bin\debug)

 

仔細檢查NHibernate 配置文件 (hibernate.cfg.xml) 中或在映射文件 (Product.hbm.xml)中是否有錯別字,最後檢查映射文件 (Product.hbm.xml)是否設置為"嵌入的資源"的"生成操作"。如果測試成功,才繼續。

 

我們第一次的 CRUD 操作

 

現在很明顯我們的系統已是準備好開始了。我們成功地實現了我們的領域模型,定義映射文件和配置 NHibernate。最後我們使用 NHibernate 從我們的領域模型 (和我們映射文件) 自動生成資料庫架構。

 

在 DDD (參考Eric Evans的《領域驅動設計》) 的精神,我們為所有的 crud 操作(創建、 讀取、 更新和刪除)定義了Repository。Repository介面是領域模型不實現的一部分!執行是特定的基礎設施。我們要保持我們的領域模型和持久化無關 (PI)。

 

譯者的話:這一段我不知道該如何去翻譯它,但我可以解釋它的意思。它的大致意思是根據DDD的思想,領域模型Domain裡面不應該有和持久化有關的東西,比如我們的Product中不該包含資料庫CRUD操作,而這些CRUD的基礎操作該在倉儲Repository介面中實現。

 

到我們的 FirstSolution 項目的Domain文件夾中添加一個新的介面。把它叫做 IProductRepository。讓我們定義以下介面

 

using System;
using System.Collections.Generic;
 
namespace FirstSolution.Domain
{
 public interface IProductRepository
 {
  void Add(Product product);
  void Update(Product product);
  void Remove(Product product);
  Product GetById(Guid productId);
  Product GetByName(string name);
  ICollection<Product> GetByCategory(string category);
 }
}

 

添加一個類 ProductRepository_Fixture 到測試項目下,並添加下麵的代碼

 

[TestFixture]
 public class ProductRepository_Fixture
 {
  private ISessionFactory _sessionFactory;
  private Configuration _configuration;
 
  [TestFixtureSetUp]
  public void TestFixtureSetUp()
  {
   _configuration = new Configuration();
   _configuration.Configure();
   _configuration.AddAssembly(typeof (Product).Assembly);
   _sessionFactory = _configuration.BuildSessionFactory();
  }
 }

 

在 TestFixtureSetUp 方法的第四行,我們創建一個session factory。這是一個開銷很大的過程,因此程式運行期間應該只執行一次。這就是為什麼把它放到這種測試期間只執行一次的方法的原因。

 

要保持我們測試方法無副作用,每個測試方法執行之前,我們重新創建我們的資料庫架構。因此我們添加下麵的方法

 

[SetUp]

  public void SetupContext()

  {

   new SchemaExport(_configuration).Execute(false, true, false, false);

  }

 

譯者的話:NHibernate3.0中,只有3個參數。new SchemaExport(cfg).Execute(false,true,false);

 

現在我們可以實現向資料庫中添加一個新的Product實例的測試方法。添加一個新的文件夾名為Repositories到 FirstSolution 項目。到此文件夾下添加一個類 ProductRepository。使 ProductRepository 實現 IProductRepository 介面。

 

using System;
using System.Collections.Generic;
using FirstSolution.Domain;
namespace FirstSolution.Repositories
{
public class ProductRepository : IProductRepository
{
  public void Add(Product product)
  {
   throw new NotImplementedException();
  }
  public void Update(Product product)
  {
   throw new NotImplementedException();
  }
  public void Remove(Product product)
  {
   throw new NotImplementedException();
  }
  public Product GetById(Guid productId)
  {
   throw new NotImplementedException();
  }
  public Product GetByName(string name)
  {
   throw new NotImplementedException();
  }
  public ICollection<Product> GetByCategory(string category)
  {
   throw new NotImplementedException();
  }
}
}

 

操作數據

 

現在回到ProductRepository_Fixture測試類和實現第一個測試方法

  [Test]

  public void Can_add_new_product()

  {

   var product = new Product {Name = "Apple", Category = "Fruits"};

   IProductRepository repository = new ProductRepository();

   repository.Add(product);

  }

 

首次運行的測試方法將失敗,因為我們的倉儲類未實現 Add 方法。讓我們實現它。但是,等一等,我們必須首先定義一個小的Helper類提供我們NHibernate session對象上的需求。

 

using FirstSolution.Domain;
using NHibernate;
using NHibernate.Cfg;
namespace FirstSolution.Repositories
{
public class NHibernateHelper
{
  private static ISessionFactory _sessionFactory;
  private static ISessionFactory SessionFactory
  {
   get
   {
    if(_sessionFactory == null)
    {
     var configuration = new Configuration();
     configuration.Configure();
     configuration.AddAssembly(typeof(Product).Assembly);
     _sessionFactory = configuration.BuildSessionFactory();
    }
    return _sessionFactory;
   }
  }
  public static ISession OpenSession()
  {
   return SessionFactory.OpenSession();
  }
}
}

運行期間,不管客戶端何時需要一個新的session,此類只創建session factory第一次。

 

現在我們可以定義 Add 方法在 ProductRepository 中,如下所示

 

public void Add(Product product)

  {

   using (ISession session = NHibernateHelper.OpenSession())

    using (ITransaction transaction = session.BeginTransaction())

    {

     session.Save(product);

     transaction.Commit();

    }

  }

 

第二次運行的測試方法會再次失敗並顯示以下消息

 

譯者的話:

 

這是因為 NHibernate 是預設情況下配置為使用延遲載入的所有實體。這是推薦的方法,我強烈建議不要更改,為了最大的靈活性。

 

我們怎樣才能解決這個問題?很容易,讓領域模型中所有屬性 (方法) 加上Virtual關鍵字即可。讓我們為我們的Product類加上這個。

 

public class Product

 {

  public virtual Guid Id { get; set; }

  public virtual string Name { get; set; }

  public virtual string Category { get; set; }

  public virtual bool Discontinued { get; set; }

 }

 

現在再次運行測試。它應該會成功,我們得到以下輸出

 

譯者的話:

 

請註意NHibernate輸出的 sql 語句。

 

現在我們已經成功地向資料庫插入一個新的Product。但讓我們測試它是否真的是這樣。讓我們來擴展我們的測試方法

 

[Test]
  public void Can_add_new_product()
  {
   var product = new Product {Name = "Apple", Category = "Fruits"};
   IProductRepository repository = new ProductRepository();
   repository.Add(product);
 
   // use session to try to load the product
   using(ISession session = _sessionFactory.OpenSession())
   {
    var fromDb = session.Get<Product>(product.Id);
    // Test that the product was successfully inserted
    Assert.IsNotNull(fromDb);
    Assert.AreNotSame(product, fromDb);
    Assert.AreEqual(product.Name, fromDb.Name);
    Assert.AreEqual(product.Category, fromDb.Category);
   }
  }

再次運行測試。希望它會成功......

 

現在我們準備也實現repository中的其他方法。為了測試這我們寧願要一個repository  (即資料庫表) 已經包含了一些產品。沒有什麼比這更簡單。只是添加 CreateInitialData 方法,如下所示添加到測試類

 

private readonly Product[] _products = new[]
     {
      new Product {Name = "Melon", Category = "Fruits"},
      new Product {Name = "Pear", Category = "Fruits"},
      new Product {Name = "Milk", Category = "Beverages"},
      new Product {Name = "Coca Cola", Category = "Beverages"},
      new Product {Name = "Pepsi Cola", Category = "Beverages"},
     };
  private void CreateInitialData()
  {
   using(ISession session = _sessionFactory.OpenSession())
    using(ITransaction transaction = session.BeginTransaction())
    {
     foreach (var product in _products)
      session.Save(product);
     transaction.Commit();
    }
  }

(在創建架構調用後) 從 SetupContext 方法調用此方法。現在每次資料庫架構創建資料庫後填充一些產品。

讓我們測試用下麵的代碼庫的更新方法

 

[Test]
  public void Can_update_existing_product()
  {
   var product = _products[0];
   product.Name = "Yellow Pear";
   IProductRepository repository = new ProductRepository();
   repository.Update(product);
   // use session to try to load the product
   using (ISession session = _sessionFactory.OpenSession())
   {
    var fromDb = session.Get<Product>(product.Id);
    Assert.AreEqual(product.Name, fromDb.Name);
   }
  }

第一次運行時此代碼將失敗,因為Update方法尚未在Repository中實現。註︰ 這是預期的行為,因為在 TDD 第一次運行測試時它應該總是失敗 !

 

譯者的話:這篇快速開始的入門教程水有點深,又是DDD,又是TDD,嚇死人了,沒接觸過的人可以忽略。同時也可見NHibernate更多是面向一些資深的面向對象程式員,可悲的是很多程式員未入門時就接觸到了它。嘆息!

 

類似於 Add 方法我們實現Repository中的 Update 方法。唯一的區別是我們調用NHibernate session對象的update 方法而不是Save方法。

 

  public void Update(Product product)

  {

   using (ISession session = NHibernateHelper.OpenSession())

   using (ITransaction transaction = session.BeginTransaction())

   {

    session.Update(product);

    transaction.Commit();

   }

  }

 

再次運行測試希望它成功。

 

Delete 方法是直截了當。測試是否真的已刪除記錄時,我們只是斷言由會話的 get 方法返回的值是等於 null。這裡是測試方法

 

    [Test]

  public void Can_remove_existing_product()

  {

   var product = _products[0];

   IProductRepository repository = new ProductRepository();

   repository.Remove(product);

 

   using (ISession session = _sessionFactory.OpenSession())

   {

    var fromDb = session.Get<Product>(product.Id);

    Assert.IsNull(fromDb);

   }

  }

 

Repository中刪除方法的實現

 

  public void Remove(Product product)

  {

   using (ISession session = NHibernateHelper.OpenSession())

    using (ITransaction transaction = session.BeginTransaction())

    {

     session.Delete(product);

     transaction.Commit();

    }

  }

 

查詢資料庫

 

我們仍然必須執行查詢的資料庫對象的三個方法。我們先從最容易的一個,GetById。我們首先編寫測試

 

[Test]

  public void Can_get_existing_product_by_id()

  {

   IProductRepository repository = new ProductRepository();

   var fromDb = repository.GetById(_products[1].Id);

   Assert.IsNotNull(fromDb);

   Assert.AreNotSame(_products[1], fromDb);

   Assert.AreEqual(_products[1].Name, fromDb.Name);

  }

 

然後完成測試的代碼

 

  public Product GetById(Guid productId)

  {

   using (ISession session = NHibernateHelper.OpenSession())

    return session.Get<Product>(productId);

  }

 

現在,那很簡單。為以下兩種方法,我們使用session對象的新方法。讓我們開始用 GetByName 方法。像往常一樣我們先寫測試

 

    [Test]

  public void Can_get_existing_product_by_name()

  {

   IProductRepository repository = new ProductRepository();

   var fromDb = repository.GetByName(_products[1].Name);

 

   Assert.IsNotNull(fromDb);

   Assert.AreNotSame(_products[1], fromDb);

   Assert.AreEqual(_products[1].Id, fromDb.Id);

  }

 

GetByName 方法的實現可以通過使用兩個不同的方法。第一使用 HQL (Hibernate Query Language) 和第二個 HCQ (Hibernate Criteria Query)。讓我們開始使用 HQL。HQL 是面向對象的查詢語言 SQL 類似 (但不是等於)。

 

譯者的話:他指的第一種方法HQL是這個樣子的。

 

在上面的示例中我介紹了常用的技術使用 NHibernate 時。它被稱為fluent介面。作為結果的代碼是簡練也更易於理解。你可以看到一個 HQL 查詢是一個字元串,它可以具有嵌入 (命名) 參數。參數使用首碼 ':'。NHibernate 定義很多的helper方法 (如示例中使用 SetString),將各種類型的值分配給這些參數。最後通過使用 UniqueResult 我告訴 NHibernate 希望只有一條記錄返回。如果多個然後引發異常,HQL 查詢將返回一條記錄。要獲取更多的信息 HQL 請閱讀線上文檔。

 

第二個版本使用criteria query來搜索請求的Product。

 

  public Product GetByName(string name)

  {

   using (ISession session = NHibernateHelper.OpenSession())

   {

    Product product = session

     .CreateCriteria(typeof(Product))

     .Add(Restrictions.Eq("Name", name))

     .UniqueResult<Product>();

    return product;

   }

  }

 

NHibernate 的許多用戶認為這種做法是更多面向的對象。在另一方面編寫的criteria語法複雜查詢可以迅速成為難以理解。

 

實現的最後一個方法是 GetByCategory。此方法返回Product的列表。測試可以實現,如下所示

 

[Test]

  public void Can_get_existing_products_by_category()

  {

   IProductRepository repository = new ProductRepository();

   var fromDb = repository.GetByCategory("Fruits");

 

   Assert.AreEqual(2, fromDb.Count);

   Assert.IsTrue(IsInCollection(_products[0], fromDb));

   Assert.IsTrue(IsInCollection(_products[1], fromDb));

  }

 

  private bool IsInCollection(Product product, ICollection<Product> fromDb)

  {

   foreach (var item in fromDb)

    if (product.Id == item.Id)

     return true;

   return false;

  }

 

方法本身可能包含下麵的代碼

 

  public ICollection<Product> GetByCategory(string category)

  {

   using (ISession session = NHibernateHelper.OpenSession())

   {

    var products = session

     .CreateCriteria(typeof(Product))

     .Add(Restrictions.Eq("Category", category))

     .List<Product>();

    return products;

   }

  }

 

摘要

 

在這篇文章中我已經給你如何實現基本示例領域模型,定義映射到資料庫以及如何配置 NHibernate 能夠持久化領域對象在資料庫中。我給你展示瞭如何通常編寫和測試您的領域對象的 CRUD 方法。我拿MS SQL Compact Edition 作為示例資料庫,但可以使用任何其他受支持的資料庫 (你只需要相應地更改 hibernate.cfg.xml 文件)。我們沒有依賴於外部框架或工具以外的資料庫和 NHibernate 本身 (.NET 當然從來沒有計算在內)。

 

譯者的話:終於翻譯完了,這篇快速開始非常適合初學者,因為提供的例子是可以被實現的,而且可以同時入門DDD和TDD,看得出作者非常用心。而我也在其中加入了批註和補充了顯示不了的圖片。

花了很多時間,想想我花時間在翻譯的時候,一個跟我長得很像的老司機開著滴滴又開直播地賺錢,我忽然感慨,有些人也許永遠都是在燃燒自己。

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我們知道在iOS開發時,控制項UITextField有個placeholder屬性,UITextField和UITextView使用方法基本類似,有兩個小區別:1.UITextField單行輸入,而UITextView可以多行輸入。2.UITextField有placeholder屬性,而UIText ...
  • cocoapods簡介: cocoapods簡介: cocoapods 是iOS的類庫管理工具,可以讓開發者很方便集成各種第三方庫,而不用去網站上一個個下載,再一個個文件夾的拖進項目中,還得添加相關的系統依賴庫。只需要安裝好cocoapods,然後編寫好Podfile,最好在終端輸入一行命令,就可以 ...
  • 在生產環境下麵對紛繁的業務處理場景,我們知道要處理很多邏輯代碼,其中有個叫枚舉(也稱窮舉),當處理這類事務時,會產生大量的迴圈執行,而迴圈是最耗CPU的,大量的迭代計算,可直接拉低計算速度,怎麼處理這類問題呢? 對於事務的不定項的選擇幾率,都會有一定的規律,比如說事件的概率發生,根據概率論的知識,我 ...
  • DMA(Direct Memory Access),直接存儲器訪問。DMA傳輸方式無需CPU直接控制傳輸,通過硬體為RAM與I/O設備開闢一條直接傳送數據的通路,使CPU效率大大提高。stm32f103有2個DMA控制器,DMA1有7個通道,DMA2有5個通道,專門用來管理來自外設對存儲器的訪問請求 ...
  • 1:打開任務管理器, [運行新任務] 2:(勾上以系統管理員許可權創建此任務) 輸入 cmd 3:進入要安裝的軟體所在的目錄:cd D:\111_安裝包\submit 3 (本文以安裝submit 為例子) 4:輸入命令:Sublime Text Build 3083 x64 Setup.exe 就會 ...
  • 定義這樣一個方法,然後接收前臺傳過來的值,調用這個方法就行了.. ...
  • 這篇文章我們開始看一下ActionFilter,從名字上其實就大概知道ActionFilter就是Action上的Filter,對吧,那麼Action上的Filter大概有幾個呢??? 這個問題其實還是蠻簡單的,因為我們聽說Mvc本身就是一個擴展性極強的框架,自然就是層層有攔截,層層有過濾,對吧,比 ...
  • 前言: 你先得知道HelpPageConfig文件,不知道說明你現在不需要這個,所以下文就不用看了,等知道了再看也不急.當然如果你很知道這個,下文也不用看了,因為你會了. 方法一: 方法二: 自定義一個支持從目錄載入xml文檔的XmlDocumentationProvider 使用方法: 使用方法: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...