Java進擊C#——應用開發之Linq和EF

来源:http://www.cnblogs.com/hayasi/archive/2016/10/21/5980269.html
-Advertisement-
Play Games

上一章筆者對於WinForm開發過程用到的幾個知識點做了講解。筆者們可以以此為開端進行學習。而本章我們來講一個跟ORM思想有關的知識點。在講之前讓我們想一下關於JAVA的hibernate知識點。hibernate也是ORM框架。記得hibernate裡面有一個叫HQL。先不管HQL的好與壞。主要是 ...


本章簡言

上一章筆者對於WinForm開發過程用到的幾個知識點做了講解。筆者們可以以此為開端進行學習。而本章我們來講一個跟ORM思想有關的知識點。在講之前讓我們想一下關於JAVA的hibernate知識點。hibernate也是ORM框架。記得hibernate裡面有一個叫HQL。先不管HQL的好與壞。主要是明白HQL的目地是什麼。ORM的思想就是為了讓用戶在操作數據的時候用上面向對象的思想來看,而不是二維數據了。所以HQL筆者認為就是一個面向對象思想的SQL語句。那麼為什麼筆者要講到HQL呢?事實上筆者認為Linq有一點跟他類似。如果項目架構是三層的話,就是讓業務層的開發人員不用在看二維數據了。就連SQL語句都是面向對象思想形式來操作了。而EF(Entity Framework)可以說就是hibernate。即是可以理解為Linq的數據源。但是HQL要在hibernate上面才能有效果。Linq卻可以不用EF。

Linq語法

.NET對於Linq知識的分類讓筆者有時候覺得很無力。為什麼呢?最早的時候筆者認為Linq知識點分三大塊。分別為Linq to SQL、Linq to Entity、Linq to Database。隨著對Linq使用的增加卻發現還有Linq to Xml 、Linq to Excel等。筆者想讀者們是不是看出門道來了。可以說.NET在設計Linq的時候,應該是有充分的想過將來擴展的問題。當然這不是本章的目標。筆者在開發過程中最常用的就是Linq to SQL和 Linq to Entity。另外還有一個叫Linq to Object.對於Linq to Object筆者一直認為就是Linq to Entity。筆者的意思是指他們的知識該應放在一塊。好了。先筆者講一下關於Linq to SQL。

對於Linq to SQL來講,只要學習SQL語法的人都不用擔心很容易就上手。記得筆者學習的時候,一看我去不就HQL的另一種形態嗎?當然 HQL可不是Linq還是要學習一下的。講那麼多沒有用。用列子才是最好的。

一、建立EF環境。先建一個項目,然後通過NUGET來獲得對應的EF的DLL。對於NUGET是什麼。相信看過《Java進擊C#——項目開發環境》的人應該可以瞭解到。選擇“引用”右擊》管理Nuget程式包。

相信看了上面的圖片的時候,我們已經發現了EntityFramework了吧。點擊“安裝”就可以了。這個時候項目就會多出一個叫packages.config文件。這裡面記錄著當前安裝的dll信息。同時物理目錄裡面會多出一個文件夾packages來存在這些dll。

我們看到引用裡面多出了關於EF的引用dll。這個時候我們就可以做EF的事情了。

二、新建EF上下文。EF有一個很重要的類。可以說是學習EF的核心點。這個類就是DbContext。筆者新建一類叫AomiContext繼承他。如下

public class AomiContext : DbContext
{

}

DbContext類有幾個構造函數。筆者這裡講一個常用的吧。如下

 public DbContext(string nameOrConnectionString);

就是個構造函數意思就是傳一個連接字元串或是配置文件的連接字元的配置名。記得上一節中講的App.config了吧。沒有錯就是要用到他。看一下筆者寫的內容吧。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="aomi" connectionString="Data Source=.;Initial Catalog=Ado;Persist Security Info=True;User ID=sa;Password=123" providerName="System.Data.SqlClient"/>
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

上面的connectionStrings部分是筆者自己寫的。其他是自動生成的。.NET自己有一個配置連接字元串的節點。我們就是在這個節點上寫入自己的連接就可以了。

<add name="aomi" connectionString="Data Source=.;Initial Catalog=Ado;Persist Security Info=True;User ID=sa;Password=123" providerName="System.Data.SqlClient"/>

好了。接下來就是把AomiContext類修改一下。讓他跟對應的連接字元串的配置發生關係。如下

 public class AomiContext : DbContext
    {
        public AomiContext()
            : base("Aomi")
        { }
    }

看到紅色部分的代碼了吧。把Aomi就是對應上面配置add節點的name的值。這個時候EF會自己去配置文件裡面去找。

三、建立表和類的映射。

對應資料庫的表:

CREATE TABLE [dbo].[Catalogs](
    [ID] [int] NOT NULL,
    [CatalogName] [nvarchar](50) NULL,
    [CatalogCode] [nvarchar](50) NULL,
 CONSTRAINT [PK_Catalogs] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

對應資料庫的數據

INSERT [dbo].[Catalogs] ([ID], [CatalogName], [CatalogCode]) VALUES (1, N'小吃', N'c0001')
INSERT [dbo].[Catalogs] ([ID], [CatalogName], [CatalogCode]) VALUES (2, N'電腦', N'c0002')

筆者建一個類用於跟資料庫裡面的表相對應。這個時候要記得屬性要跟表裡裡面的列名一樣子才行。代碼如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LinqExample
{
    public class Catalogs
    {
        public int ID { set; get; }

        public string CatalogName { set; get; }
  
        public string CatalogCode { set; get; }
    }
}

有了對應的類之後,還不行。我們還要修改一下AomiContext類。這樣子就可以通過AomiContext類來訪問對應的類對象了。即是數據了。如下

    public class AomiContext : DbContext
    {
        public AomiContext()
            : base("Aomi")
        { }

        public IDbSet<Catalogs> Catalogs { set; get; }
    }

四、執行EF。

 class Program
    {
        static void Main(string[] args)
        {
            using (AomiContext ac = new AomiContext())
            {
                IQueryable<Catalogs> queryable = from c in ac.Catalogs select c;
                List<Catalogs> catalogList = queryable.ToList();

                foreach (Catalogs catalog in catalogList)
                {
                    Console.WriteLine(string.Format("ID:{0} CatalogName:{1}", catalog.ID, catalog.CatalogName));
                }
            }

            Console.ReadKey();
        }
    }

執行結果:

從上面的例子我們可以看到用了from c in ac.Catalogs select c;來獲得對應的數據。這便是linq to sql。簡章講他是一個面向對象的SQL語句。SQL語句是以select開頭,結尾不確定。而linq to sql一般是以from開頭,以select結尾。表示從哪一個數據源開始,最後要以什麼樣子返回。可是我們可以看到他返回是一個IQueryable<T>類型。事實這個時候他並沒有去執行獲得數據。可以解理為他現在只是去組裝SQL語句。只到queryable.ToList();才是去執行獲得數據。為了學習上的方便筆者又加幾個關鍵字讓大家看一下。

using (AomiContext ac = new AomiContext())
            {
                IQueryable<Catalogs> queryable = from c in ac.Catalogs where c.CatalogName.Contains("吃") orderby c.CatalogCode ascending select c;
                List<Catalogs> catalogList = queryable.ToList();

                foreach (Catalogs catalog in catalogList)
                {
                    Console.WriteLine(string.Format("ID:{0} CatalogName:{1}", catalog.ID, catalog.CatalogName));
                }
            }

看完了linq to sql之後,讓我看一下關於linq to entity又是什麼東東呢?可是這樣子講linq的語法都相像。只是用法和寫法不一樣子而以。把上面的例子變一變吧。

 using (AomiContext ac = new AomiContext())
            {
                //IQueryable<Catalogs> queryable = from c in ac.Catalogs where c.CatalogName.Contains("吃") orderby c.CatalogCode ascending select c;
                IQueryable<Catalogs> queryable = ac.Catalogs.Where(t => t.CatalogName.Contains("吃")).OrderBy(t => t.CatalogCode).Select(c=> c);
                List<Catalogs> catalogList = queryable.ToList();
                foreach (Catalogs catalog in catalogList)
                {
                    Console.WriteLine(string.Format("ID:{0} CatalogName:{1}", catalog.ID, catalog.CatalogName));
                }
            }

看樣子筆者不用多說也明白。就是變成了對應的關鍵字方法而以。沒有錯。就是這樣子。這個時候筆者就可以這樣子認為不管是Linq to entity還是Linq to sql都必須要有對應的數據源。這裡EF就是為他們提供數據源的。他們倆個對應都是返回IQueryable<T>類型。只是Linq to entity是用方法。而Linq to sql更多像SQL語句。

好了。讓我們看一下關於linq to object吧。可以這樣了講吧——不管是Linq to sql還是linq to entity他們倆個都離不開linq to object。linq to object是專對記憶體中的數據進行處理。我們可以看到上面例子中有出現一段queryable.ToList()。如果筆者說ToList()是linq to object會不會有人噴我。為什麼筆者說他是linq to object呢?主要是ToList()是對於IEnumerable<T>進行靜態擴展的。IEnumerable<T>一般都是用於數組和集合。位於記憶體中的。而上面都是專對於IQueryable<T>類型的。好了。如果你實在覺得筆者分的不對的話,那就是不要分了。都為Linq語法就行了。linq還提供了一些比較常用的方法。

First:返回第一個數據。沒有數據就出生異常。同時也可以傳入第一個數據的條件作為參數。如queryable.First(t => t.CatalogName.Contains("吃"));。

FirstOrDefault:同樣子返回第一個數據,沒有數據的話,就返回NULL。同時也可以傳入第一個數據的條件作為參數。

Last:同理獲得最後一方法。用法同上一樣子。

LastOrDefault:同上一樣子。跟FirstOrDefault用法一樣子。

Skip:給定一個數字,那麼數字前面都不會取出來,後以的才取出來。一般都跟Take方法一起用來作分頁功能。

Take:表示要返回的數量。你可以理解為SQL語句中的TOP關鍵字。

讓筆者舉個linq to object的列子吧。

List<string> src = new List<string>();
src.Add("a1");
src.Add("b2");
src.Add("c4");
src.Add("d5");
string value = src.First(t => t.StartsWith("a"));
Console.WriteLine(value);

註意:筆者是這樣子分的。一般靜態擴展IQueryable<TSource> 的方法屬於linq to entity。而靜態擴展IEnumerable<TSource>則為linq to object。倆者很像。只是linq to entity必須要有數據源。linq to object一般是處理記憶體數據。

Entity Framework

Entity Framework做為ORM框架之一。所以ORM框架必須有的東西他多有。學習Entity Framework就必須知道他有什麼知識點。Entity Framework根據開發模式的不同分為Code First、Model First和Database First。讓筆者用土一點的說法來講吧。

Code First模式:就是通過寫代碼來生成對應的資料庫和表。

Model First模式:事實上跟Code First有一點像。只是他用了.NET的一個叫xxx.edmx的文件來操作而以。通過他來生成對應的資料庫和表。

Database First模式:卻跟前面倆個相反。先建資料庫和表在生成對的類。即是代碼。

我們現在要學習Entity Framework。筆者個人意見讀者們最好選擇Code First模式來學習。為什麼。不管是Model First模式還是Database First模式大部分都是軟體工具幫你生成對應的代碼。所以很多東西我們根本看不到。而Code First模式就是要開發人員手把手的寫了。記得筆者在使用hibernate的時候。並沒有說只做一邊的事情。一般都是資料庫的表建完之後。還是要去寫對應的映射配置文件(xxx.hbm.xml)。好一點就自己寫一個代碼生成器。Entity Framework意圖就是幫開發人員做掉一邊的工作。不過這也是筆者不喜歡的。正因為這樣子Entity Framework多出了一個知識點那就是數據遷移。我們都知道在開發的過程中。可能會因為當初表沒有設計好。突然發現需要增加一個欄位。這樣個時候Entity Framework就要做很多事情。假設我們用的是Code First吧。我們在代碼中的類增加一個屬性。這個時候Entity Framework就是要去判斷哪些屬性是舊的。哪些屬性是修改的。哪些屬性是新增加的。然後Entity Framework在更新資料庫。就是Entity Framework的數據遷移。

從上面的講解中我們知道EF想幫我做了另一半的事情,所以就必須對資料庫操作才行。那麼就是存在對資料庫設置,對錶設置,對數據操作。以下全是在在Code First模式下的講說。

1、EF對資料庫的設置。執行代碼的時候,EF會去判斷是否存在對應的資料庫。而對資料庫進行操作。是創建還是刪除在創建。還是更新呢?主要看你設置對應的資料庫操作的模式。那麼EF為我們提供了三個。當然我們可以自己寫一個。三個類都在System.Data.Entity命名空間下。分別是CreateDatabaseIfNotExists、DropCreateDatabaseAlways、DropCreateDatabaseIfModelChanges。文英好的人都能看得懂是什麼一會事。

 public AomiContext()
            : base("Aomi")
        {
            Database.SetInitializer<AomiContext>(new CreateDatabaseIfNotExists<AomiContext>());
        }

註意:關於Database.SetInitializer方法的賦值是可以放在別的地方。但一定要執行EF之前。

2、EF對錶的設置。這些設置大部是關於表和表與表之間的關係如何體現在類和類與類之間的關係。下麵筆者做了一個簡單的映射例子。

 public class AomiContext : DbContext
    {
        public AomiContext()
            : base("Aomi")
        { }

        public IDbSet<Catalogs> Catalogs { set; get; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Configurations.Add(new CatalogsMap());

        }
    }

下麵CatalogsMap類就相當於映射配置文件(xxx.hbm.xml)。其中包括一對一,一對多,多對多之類的關係也是在這裡配置。有一點要註意的是上面紅色代碼。即是把映射關係加入EF配置裡面

 public class CatalogsMap : EntityTypeConfiguration<Catalogs>
    {
        public CatalogsMap()
        {
            this.HasKey(t => t.ID);
            this.Property(t => t.CatalogName).HasColumnName("CatalogName");
            this.Property(t => t.CatalogCode).HasColumnName("CatalogCode");
        }
    }

3、對數據的操作。對數據的操作一般就是增刪改查了。

增加:

using (AomiContext ac = new AomiContext())
{
      Catalogs catalogs = new Catalogs();
      catalogs.ID = 6;
      catalogs.CatalogName = "商品";
      catalogs.CatalogCode = "s0001";
      ac.Catalogs.Add(catalogs);
                
      ac.SaveChanges();
}

事實上面的代碼是沒有問題。可是執行的時候卻會發生錯誤。為什麼呢?筆者也不是清楚什麼原因。查找沒有問題。可是在增加卻會出問題。讓我看一下異常吧。這裡筆者只複製出一部分。

       InnerException: System.Data.SqlClient.SqlException
            _HResult=-2146232060
            _message=不能將值 NULL 插入列 'ID',表 'Ado.dbo.Catalogs';列不允許有 Null 值。INSERT 失敗。
語句已終止。
            HResult=-2146232060
            IsTransient=false
            Message=不能將值 NULL 插入列 'ID',表 'Ado.dbo.Catalogs';列不允許有 Null 值。INSERT 失敗。
語句已終止。
            Source=.Net SqlClient Data Provider
            ErrorCode=-2146232060
            _doNotReconnect=false

他說我的ID沒有設置值,可是我設置了。筆者想你們一定會認為是沒有設置標識。也就是自動增長。不是這樣子的。筆者本來就是沒有想過要自動增長啊。那麼為什麼會錯呢?事實筆者也是以這樣子的角度去想的。會不會EF預設就認為ID是自動增長。因為ID是int類型的。又是主鍵。所以我就在映射配置裡面加了一段代碼。如下

 public class CatalogsMap : EntityTypeConfiguration<Catalogs>
    {
        public CatalogsMap()
        {
            this.HasKey(t => t.ID);
            this.Property(t => t.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
            this.Property(t => t.CatalogName).HasColumnName("CatalogName");
            this.Property(t => t.CatalogCode).HasColumnName("CatalogCode");
        }
    }

紅色部分就是增加的代碼。這個時候就不會出錯了。那麼這段代碼是什麼意思。就是告訴EF這裡的ID只是普通的。沒有別的設置。

修改:

using (AomiContext ac = new AomiContext())
{
     Catalogs updateCatalogs = ac.Catalogs.FirstOrDefault(t => t.ID == 4);
     updateCatalogs.CatalogName = "紙類";
                
     ac.SaveChanges();
}

刪除:

using (AomiContext ac = new AomiContext())
{
 Catalogs deleteCatalogs = ac.Catalogs.FirstOrDefault(t => t.ID == 1);
 ac.Catalogs.Remove(deleteCatalogs);
                
 ac.SaveChanges();
}

筆者在做EF的增刪改的時候,我心裡面一直在想倆個問題?

第一:EF並沒有像Hibernate那樣子。有增加的方法和更新的方法。他只有一種概念那就是數據有沒有發生改變。根據改變數據來更新資料庫的數據。

第二:Hibernate在處理對象的時候。會用到對象的三種狀態。這三種狀態在不同的書裡面有不同的叫法。筆者一般喜歡叫他們為普通狀、持久狀、游離狀。可是如果把Hibernate這個知識放在EF這邊來的話,也不是說不可以。只是覺得這個時候有一點怪。EF這邊並沒有類似相關的說明。可是筆者還是覺得有必要用他放在EF這邊。為什麼呢?先讓我們看一下情況吧。如果我們把上面的ID變成了標識。即為自動增長。在增加的時候就沒有必要去設置這個值。那麼增加成功之後我們要如果去獲得對應的ID值呢?難道在獲取一遍嗎?顯然不是。如下。

class Program
    {
        static void Main(string[] args)
        {
            using (AomiContext ac = new AomiContext())
            {
                Catalogs catalogs = new Catalogs();
                catalogs.ID = 0;
                catalogs.CatalogName = "商品";
                catalogs.CatalogCode = "s0001";
                ac.Catalogs.Add(catalogs);

                ac.SaveChanges();

                Console.WriteLine("ID:" + catalogs.ID);
            }

            Console.ReadKey();
        }
    }

筆者把上面的數據全部刪除掉。並且把Catalogs表的列ID修改為標識。即是自動增長。在新建Catalogs對象的時候把ID設置為0。然後我們在看一下增加成功之後ID是不是還是為0。但是記得把CatalogsMap類裡面的映射配置修改一下。修改如下。

 this.Property(t => t.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

好了,讓我們看一下結果值是多少。如下。我們看到是7。為什麼不是0。筆者的SQL Server的標識是從6開始的。所以這邊是7。如果你們一開始的話。是1。但決對不是0。為什麼?就是因為對象變成了持久狀了。

普通狀:就是正常用關鍵字new來創建。

持久狀:就是通過EF之後,比如增加。這個時候對象跟資料庫同步。

游離狀:關閉EF之後的對象。不過筆者認為EF沒有這種狀態。因為Hibernate有喚醒這個功能。

本章總結

本章主要講到關於Linq和EF的知識點。Linq的一些入門用法和EF的基本知識點。當然,有關EF的類與類之間的關係和數據遷移筆者筆者必沒有說。希望讀者們自行查看。


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

-Advertisement-
Play Games
更多相關文章
  • 文檔目錄 本節內容: 簡介 關於 IAbpSeesion 註入會話 會話屬性 用戶標識符 關於 IAbpSeesion 簡介 如果一個應用需要登錄,它就需要知道當前用戶在執行的操作。儘管Asp.net自身在展現層提供了Session(會話)對象,而ABP提供IAbpSession介面來獲取當前用戶和 ...
  • 文檔目錄 本節內容: 什麼時依賴註入 傳統方式的問題 解決方案 構造器註入模式 屬性註入模式 依賴註入框架 ABP 依賴註入基礎 註冊依賴 約定註入 輔助介面 自定義/直接 註冊 使用IocManager 使用Castle Windsor API 解析 構造器和屬性註入 IIocResolver 和 ...
  • 第一次在項目中遇到遠程訪問postgresql資料庫的,當時經常會出現連接資料庫的錯誤,連接字元串出現亂碼現象 解決方案 在配置文件中添加連接字元串 後臺代碼 最後連接成功 ...
  • 在.net框架體系內,反射特性較多的應用到。反射的相關定義分為兩種。 自然解釋:射是一種自然現象,表現為受刺激物對刺激物的逆反應;這是反射的字面解釋,我們看一下電腦編程中的反射; 編程解釋:通過 System.Reflection 命名空間中的類以及 System.Type,您可以獲取有關已載入的 ...
  • 老規矩,先簡單介紹下MQTT: MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是IBM開發的一個即時通訊協議,有可能成為物聯網的重要組成部分。該協議支持所有平臺,幾乎可以把所有聯網物品和外部連接起來,被用來當做感測器和致動器(比如通過Twitte ...
  • 在項目中,有時候一些信息不便完全顯示,只需要顯示部分信息。現在提供一些隱藏敏感信息的操作方法,主要為對信息的截取操作: 1.指定左右字元數量,中間的*的個數和實際長度有關: 2.指定左右字元數量,中間的*的個數固定: 3.“*”數量一定,設置為4個,按信息總長度的比例來取,預設左右各取1/3: 4. ...
  • 一、前言 前不久因公司產品需要完成了線上升級功能,因為編程技術不精,不敢冒然採用Socket方法實現線上升級,所以使用比較方便穩妥的WCF方式 如果考慮併發能力的話還是Socket>WCF>Remoting,所以如果你是Socket專家的話這篇你就不用看了。 二、流程 本篇主要講述一個完整的升級思路 ...
  • 在.NET項目中,我們較多的使用到加密這個操作。因為在現代的項目中,對信息安全的要求越來越高,那麼多信息的加密就變得至關重要。現在提供幾種常用的加密/解密演算法。 1.用於文本和Base64編碼文本的互相轉換 和 Byte[]和Base64編碼文本的互相轉換: (1).將普通文本轉換成Base64編碼 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...