C#基礎(chǔ)鞏固與進(jìn)階(定時(shí)語(yǔ)音播報(bào)+PDF水印+分片上傳+EF6框架)

b站視頻:2022年C#進(jìn)階教程-C#應(yīng)該學(xué)到什么程度(針對(duì)編程思維)

前提

UI框架:WinForm(基于.net framework 4.6.1)、MaterialSkin.2(v2.3.0.0)

//第一步 NuGet下載MaterialSkin.2

// 第二步 
// 初始化MaterialSkinManager
 MaterialSkinManager materialSkinManager = MaterialSkinManager.Instance;

 //將此設(shè)置為false,以禁用對(duì)非材質(zhì)蒙皮組件的背景色強(qiáng)制
 //這必須在AddFormToManager()之前設(shè)置
 materialSkinManager.EnforceBackcolorOnAllComponents = true;

 //MaterialSkinManager 屬性
 materialSkinManager.AddFormToManage(this);
 materialSkinManager.Theme = MaterialSkinManager.Themes.LIGHT;
 materialSkinManager.ColorScheme = new ColorScheme(Primary.Teal400, Primary.Teal200, Primary.Teal400, Accent.DeepOrange100, TextShade.WHITE);

ps:如果你想使用wpf到達(dá)類似界面效果可以參考。
https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit

章節(jié)

1.程序員福音-定時(shí)提醒(C#版)

會(huì)使用自定義控件

ps:等到后面學(xué)習(xí)ef6的時(shí)候 我們把數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)里面 以便打開(kāi)時(shí)能查詢到我們?cè)O(shè)置的任務(wù)

2.C#使用Apose.PDF給Pdf文件添加自定義水印

依賴:Aspose.Pdf (v10.0.0.0)

官網(wǎng):https://docs.aspose.com/pdf/net/

Stream LStream = new MemoryStream(Convert.FromBase64String(ConfigurationManager.AppSettings.Get("aposeLicense")));
new Aspose.Pdf.License().SetLicense(LStream);

ps:僅支持10.0.0.0版本以上

破解版秘鑰許可:
PExpY2Vuc2U+DQogIDxEYXRhPg0KICAgIDxMaWNlbnNlZFRvPkFzcG9zZSBTY290bGFuZCBUZWFtPC9MaWNlbnNlZFRvPg0KICAgIDxFbWFpbFRvPmJpbGx5Lmx1bmRpZUBhc3Bvc2UuY29tPC9FbWFpbFRvPg0KICAgIDxMaWNlbnNlVHlwZT5EZXZlbG9wZXIgT0VNPC9MaWNlbnNlVHlwZT4NCiAgICA8TGljZW5zZU5vdGU+TGltaXRlZCB0byAxIGRldmVsb3BlciwgdW5saW1pdGVkIHBoeXNpY2FsIGxvY2F0aW9uczwvTGljZW5zZU5vdGU+DQogICAgPE9yZGVySUQ+MTQwNDA4MDUyMzI0PC9PcmRlcklEPg0KICAgIDxVc2VySUQ+OTQyMzY8L1VzZXJJRD4NCiAgICA8T0VNPlRoaXMgaXMgYSByZWRpc3RyaWJ1dGFibGUgbGljZW5zZTwvT0VNPg0KICAgIDxQcm9kdWN0cz4NCiAgICAgIDxQcm9kdWN0PkFzcG9zZS5Ub3RhbCBmb3IgLk5FVDwvUHJvZHVjdD4NCiAgICA8L1Byb2R1Y3RzPg0KICAgIDxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT4NCiAgICA8U2VyaWFsTnVtYmVyPjlhNTk1NDdjLTQxZjAtNDI4Yi1iYTcyLTdjNDM2OGYxNTFkNzwvU2VyaWFsTnVtYmVyPg0KICAgIDxTdWJzY3JpcHRpb25FeHBpcnk+MjAxNTEyMzE8L1N1YnNjcmlwdGlvbkV4cGlyeT4NCiAgICA8TGljZW5zZVZlcnNpb24+My4wPC9MaWNlbnNlVmVyc2lvbj4NCiAgICA8TGljZW5zZUluc3RydWN0aW9ucz5odHRwOi8vd3d3LmFzcG9zZS5jb20vY29ycG9yYXRlL3B1cmNoYXNlL2xpY2Vuc2UtaW5zdHJ1Y3Rpb25zLmFzcHg8L0xpY2Vuc2VJbnN0cnVjdGlvbnM+DQogIDwvRGF0YT4NCiAgPFNpZ25hdHVyZT5GTzNQSHNibGdEdDhGNTlzTVQxbDFhbXlpOXFrMlY2RThkUWtJUDdMZFRKU3hEaWJORUZ1MXpPaW5RYnFGZkt2L3J1dHR2Y3hvUk9rYzF0VWUwRHRPNmNQMVpmNkowVmVtZ1NZOGkvTFpFQ1RHc3pScUpWUVJaME1vVm5CaHVQQUprNWVsaTdmaFZjRjhoV2QzRTRYUTNMemZtSkN1YWoyTkV0ZVJpNUhyZmc9PC9TaWduYXR1cmU+DQo8L0xpY2Vuc2U+

3.C#實(shí)現(xiàn)文件分片上傳,前端winform+后端.net core api

簡(jiǎn)述分片上傳

所謂分片上傳,也就是把文件分成一小片,形成多個(gè)文件,上傳后服務(wù)器將文件組成一個(gè)完整的文件,當(dāng)然此時(shí)需要校驗(yàn)文件的hashcode保證上傳與組成的文件是同一個(gè)文件

.net core 3.1 關(guān)于文件上傳:
https://learn.microsoft.com/zh-cn/aspnet/core/mvc/models/file-uploads?view=aspnetcore-3.1#upload-large-files-with-streaming

public static  string UploadFileHttpRequest(string url,byte[] fileBytes, string fileName, string name = "files"
                                                    , Dictionary<string,string> paramDict=null)
        {
            using (HttpClient client = new HttpClient())
            {
                try
                {
                    var content = new MultipartFormDataContent();
                    if (paramDict != null)
                    {
                        foreach (var item in paramDict)
                        {
                            content.Add(new StringContent(item.Value), item.Key);
                        }
                    }
                    // 上傳文件類型 
                    content.Add(new ByteArrayContent(fileBytes), name, fileName);

                    string result = client.PostAsync(url, content).Result.Content.ReadAsStringAsync().Result;
                    return result;
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
            }

        }


/// <summary>
/// 分片上傳(未記錄文件hash碼)
/// </summary>
/// <param name="url">上傳url</param>
/// <param name="filePath">文件位置</param>
/// <param name="sectionLen">每片長(zhǎng)度(按M為單位)</param>
/// <param name="name">文件后端接收映射的key值</param>
/// <param name="paramDict">相關(guān)參數(shù)</param>
/// <returns></returns>
public static string UploadSectionFile(string url, string filePath, int sectionLen = 5, string name = "file"
                                               , Dictionary<string, string> paramDict = null)
        {
            FileInfo file = new FileInfo(filePath);
            string result=null;
            int partLen = 1024 * 1024 * sectionLen;//5M
            long total = file.Length % partLen == 0 ? file.Length / partLen : file.Length / partLen + 1;
            byte[] sends = new byte[partLen];
            int restLen = (int)(file.Length % partLen);
            int position = 0;
            using (FileStream fileStream = file.OpenRead())
            {
                for (int i = 0; i < total; i++)
                {
                    if (i == total-1 && restLen > 0)
                    {
                        sends = new byte[restLen];
                        partLen = restLen;
                    }
                    fileStream.Read(sends, 0, partLen);
                    paramDict = paramDict??new Dictionary<string, string>();
                    if (paramDict.ContainsKey("position"))
                    {
                        paramDict.Remove("position");
                    }
                    paramDict.Add("position", position + "");//記錄文件位置
                    result = UploadFileHttpRequest(url, sends, file.Name, name, paramDict);
                    position += partLen;//位置
                }
            }
            return result;
        }
 /// <summary>
        /// 分片上傳
        /// </summary>
        /// <returns></returns>
        [HttpPost("partUpload")]
        public async Task<IActionResult> OnPostPartUploadAsync(IFormFile file,[FromForm]long position)
        {         
            if (file?.Length > 0)
            {
                long size = file.Length;
                string filePath = Path.Combine(@"F:\", file.FileName);//可以修改保存路徑
                using (var stream = System.IO.File.Open(filePath, FileMode.OpenOrCreate))
                {
                    stream.Seek(position, SeekOrigin.Begin);
                    byte[] reads = new byte[1024];
                    using (var inputStream = file.OpenReadStream())
                    {
                        int readV;
                        while ((readV = inputStream.Read(reads)) > 0)
                        {
                            await stream.WriteAsync(reads, 0, readV);
                        }
                    }
                }
                return Ok(new { msg = "上傳成功", position, size });
            }

            return Ok(new { msg = "沒(méi)有文件需要上傳", count = 0 });
        }

4.winform的數(shù)據(jù)綁定

//方式一
xxControl.DataBindings.Add(binding);

//方式二
xxControl.DataBindings.Add(propName,dataSource,memberName);

5.EF6框架(EntityFramework)

需要三張表: t_user_info t_book_info t_borrow_info

5.1 官方地址

源碼地址: https://github.com/dotnet/ef6/tree/main/src
文檔地址: https://learn.microsoft.com/zh-cn/ef/ef6/

5.2 相關(guān)集成(配置文件+代碼層面)

本地 SQL Server數(shù)據(jù)庫(kù)鏈接:

Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=C:\Users\CNC\Desktop\MusicDBContext.mdf;Initial Catalog=MusicDBContext;Integrated Security=True
Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=FileApplication.MyDbContext;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False

  • 第一步 NuGet安裝核心依賴項(xiàng)

    **第一種:輕便型**
    

    NuGet安裝 EntityFramework(v6.2.0)、MySQL.Data.Entities(v6.8.3)


<connectionStrings>
  <add name="mysqlCon" connectionString="server=127.0.0.1;port=3306;user=root;password=123456; database=book_manage;Charset=utf8" providerName="MySql.Data.MySqlClient" />
</connectionStrings>


<entityFramework>
  <!--MySql.Data.MySqlClient部分安裝后需要自己配置,而System.Data.SqlClient是安裝依賴后自己生成的-->
  <providers>
    <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
    <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />       
  </providers>
</entityFramework>

<!--安裝依賴后自動(dòng)生成的-->
<system.data>
  <DbProviderFactories>
    <remove invariant="MySql.Data.MySqlClient" />
    <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.8.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
  </DbProviderFactories>
</system.data>

第二種: 方便型
(僅安裝MySql.Data.EntityFramework,缺點(diǎn)是安裝的關(guān)聯(lián)依賴很多,見(jiàn)下圖)
直接NuGet安裝MySql.Data.EntityFramework(v8.0.30)它會(huì)把關(guān)聯(lián)的依賴項(xiàng)加入 如MySql.Data.DLL(8.0.30) + EntityFramework .DLL (v6.2.0)+EntityFramework.SqlServer.DLL (v6.2.0)

  • [圖片上傳失敗...(image-136f33-1668222314579)]
<connectionStrings>
  <!--mysql 連接信息-->
  <add name="mysqlCon" connectionString="server=127.0.0.1;user id=root;password=123456;database=smart-parking;sslmode=none;charset=utf8" providerName="MySql.Data.MySqlClient" />
</connectionStrings>

<system.data>
  <DbProviderFactories>
    <remove invariant="MySql.Data.MySqlClient" />
    <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory,MySql.Data, Version=8.0.30.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
  </DbProviderFactories>
</system.data>
  • 第二步
    建立實(shí)體 DbContext里面具體數(shù)據(jù)集

5.3 相關(guān)特性(注解)

約束注解:

https://learn.microsoft.com/zh-cn/dotnet/api/system.componentmodel.dataannotations.schema?view=net-6.0

組件模型注解:

https://learn.microsoft.com/zh-cn/dotnet/api/system.componentmodel.dataannotations?view=net-6.0&viewFallbackFrom=entity-framework-6.2.0

5.4 日志打印

自定義 DatabaseLogFormatter
通過(guò)創(chuàng)建一個(gè)派生自 DatabaseLogFormatter 并適當(dāng)替代方法的新類,可以更改記錄的內(nèi)容及其格式。 最常見(jiàn)的替代方法是:

  • LogCommand - 替代此選項(xiàng)可更改命令在執(zhí)行前的記錄方式。 默認(rèn)情況下,LogCommand 會(huì)針對(duì)每個(gè)參數(shù)調(diào)用 LogParameter;可選擇在替代中執(zhí)行相同的操作或以不同的方式處理參數(shù)。
  • LogResult - 替代此選項(xiàng)可更改執(zhí)行命令結(jié)果的記錄方式。
  • LogParameter - 替代此選項(xiàng)可更改參數(shù)記錄的格式和內(nèi)容。

例如,假設(shè)我們只想在每個(gè)命令發(fā)送到數(shù)據(jù)庫(kù)之前記錄一行。 可通過(guò)兩個(gè)替代來(lái)完成:

  • 替代 LogCommand 以格式化和寫(xiě)入單行 SQL
  • 替代 LogResult,不執(zhí)行任何操作。

代碼將如下所示:

public class OneLineFormatter : DatabaseLogFormatter
{
    public OneLineFormatter(DbContext context, Action<string> writeAction)
        : base(context, writeAction)
    {
    }

    public override void LogCommand<TResult>(
        DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext)
    {
        Write(string.Format(
                "Context '{0}' , Executing Command:\r\n '{1}'{2}",
                Context.GetType().Name,
                command.CommandText.Replace(Environment.NewLine, ""),
                Environment.NewLine));
    }

    public override void LogResult<TResult>(
        DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext)
    {
    }
}

若要記錄輸出,只需調(diào)用 Write 方法,該方法會(huì)將輸出發(fā)送到配置的寫(xiě)入委托。
(請(qǐng)注意,此代碼會(huì)簡(jiǎn)單刪除換行符,就像示例一樣。它可能無(wú)法很好地查看復(fù)雜的 SQL.)

設(shè)置 DatabaseLogFormatter
創(chuàng)建一個(gè)新的 DatabaseLogFormatter 類后,需要向 EF 注冊(cè)該類。 使用基于代碼的配置完成此操作。 簡(jiǎn)而言之,這意味著在與 DbContext 類相同的程序集中創(chuàng)建一個(gè)派生自 DbConfiguration 的新類,然后在這個(gè)新類的構(gòu)造函數(shù)中調(diào)用 SetDatabaseLogFormatter。 例如:

public class MyDbConfiguration : DbConfiguration
{
    public MyDbConfiguration()
    {
        SetDatabaseLogFormatter(
            (context, writeAction) => new OneLineFormatter(context, writeAction));
    }
}

5.5 CRUD+事務(wù)

5.5.1 封裝的DbSet

https://learn.microsoft.com/zh-cn/dotnet/api/system.data.entity.dbset-1?source=recommendations&view=entity-framework-6.2.0

//單個(gè)新增
//將給定實(shí)體以“已添加”狀態(tài)添加到集的基礎(chǔ)上下文中,這樣一來(lái),當(dāng)調(diào)用 SaveChanges 時(shí),會(huì)將該實(shí)體插入到數(shù)據(jù)庫(kù)中。
DataSet.Add(Object);


//多個(gè)新增
//將給定的實(shí)體集合添加到該集的上下文中,并將每個(gè)實(shí)體放入“添加”狀態(tài),以便調(diào)用 SaveChanges 時(shí),該實(shí)體將插入數(shù)據(jù)庫(kù)。
DataSet.AddRange(IEnumerable)   

//將在此上下文中所做的所有更改保存到基礎(chǔ)數(shù)據(jù)庫(kù)。
DbContext.SaveChanges() 

//擴(kuò)展方法
//需要引入命名空間: System.Data.Entity.Migrations
DataSet.AddOrUpdate(TEntity);
//將在此上下文中所做的所有更改保存到基礎(chǔ)數(shù)據(jù)庫(kù)。
DbContext.SaveChanges(TEntity[]);    
//單個(gè)刪除
//將給定實(shí)體標(biāo)記為“已刪除”,這樣一來(lái),當(dāng)調(diào)用 SaveChanges 時(shí),將從數(shù)據(jù)庫(kù)中刪除該實(shí)體。 請(qǐng)注意,在調(diào)用此方法之前,該實(shí)體必須以另一種狀態(tài)存在于該上下文中。
DataSet.Remove(Object)  

//多個(gè)刪除
//從設(shè)置的上下文中刪除給定的實(shí)體集合,并將每個(gè)實(shí)體放入 Deleted 狀態(tài),以便調(diào)用 SaveChanges 時(shí),將從數(shù)據(jù)庫(kù)中刪除該實(shí)體。
DataSet.RemoveRange(IEnumerable)    

//將在此上下文中所做的所有更改保存到基礎(chǔ)數(shù)據(jù)庫(kù)。
DbContext.SaveChanges() 
//方式一
//創(chuàng)建一個(gè)原始 SQL 查詢,該查詢將返回此集中的實(shí)體。
DataSet.SqlQuery(String, Object[]);

示例:SqlQuery ("SELECT * FROM dbo.表名 WHERE Author = @author", new SqlParameter ("@author", userSuppliedAuthor) ) ;

//方式二
DataSet.Find(Object[]);

5.5.2 原生SQL

DataSet.SqlQuery("dbo.表名");//sql不帶參數(shù)

DataSet.SqlQuery("dbo.表名",參數(shù)數(shù)組);//sql帶參數(shù)
DataSet.ExecuteSqlCommand(新增/修改/刪除語(yǔ)句, Object[]);
//object[] 對(duì)應(yīng)的類型=>new SqlParameter ("@author", userSuppliedAuthor)

5.5.3 自動(dòng)檢測(cè)更改

//如果跟蹤上下文中的大量實(shí)體,并且在循環(huán)中多次調(diào)用其中某個(gè)方法,則可關(guān)閉在循環(huán)期間的更改檢測(cè)來(lái)獲得顯著的性能改進(jìn)。 例如:

using (var context = new DbContext())
{
    try
    {
        context.Configuration.AutoDetectChangesEnabled = false;
        // 在循環(huán)中進(jìn)行多次調(diào)用(Add方法)
        foreach (var blog in aLotOfBlogs)
        {
            context.Blogs.Add(blog);
        }
    }
    finally
    {
        context.Configuration.AutoDetectChangesEnabled = true;
    }
}
//不要忘記在循環(huán)后重新啟用更改檢測(cè) - 我們使用了 try/finally 來(lái)確保始終重新啟用更改,即使循環(huán)中的代碼引發(fā)異常。

//禁用和重新啟用的替代方法是,使自動(dòng)檢測(cè)更改一直保持關(guān)閉狀態(tài),并且顯式調(diào)用context.ChangeTracker.DetectChanges或努力使用更改跟蹤代理。 這兩個(gè)都是高級(jí)選項(xiàng),可以輕松地在應(yīng)用程序中引入細(xì)微 bug,因此請(qǐng)謹(jǐn)慎使用它們。

//如果需要在上下文中添加或刪除多個(gè)對(duì)象,請(qǐng)考慮使用 DbSet.AddRange 和 DbSet.RemoveRange。 此方法僅在添加或刪除操作完成后自動(dòng)檢測(cè)更改一次。

5.5.4 使用事務(wù):

從 EF6 開(kāi)始,框架現(xiàn)在提供:

  1. Database.BeginTransaction():一種更簡(jiǎn)單的方法,讓用戶在現(xiàn)有的 DbContext 中自己?jiǎn)?dòng)和完成事務(wù) - 允許在同一事務(wù)中合并多個(gè)操作,因此所有已提交或所有回滾都為一個(gè)事務(wù)。 它還允許用戶更輕松地指定事務(wù)的隔離級(jí)別。
  2. Database.UseTransaction():它允許 DbContext 使用在實(shí)體框架外部啟動(dòng)的事務(wù)。

5.5.4 處理并發(fā)沖突

方案一:通過(guò) Reload(數(shù)據(jù)庫(kù)優(yōu)先)解決樂(lè)觀并發(fā)異常
方案二:在客戶端優(yōu)先時(shí)解決樂(lè)觀并發(fā)異常
方案三:自定義樂(lè)觀并發(fā)異常的解決方案
方案四:使用對(duì)象自定義樂(lè)觀并發(fā)異常的解決方案

5.6 拓展(關(guān)于遷移)

選項(xiàng)一:使用現(xiàn)有架構(gòu)作為起點(diǎn)

Code First 遷移使用存儲(chǔ)在最近遷移中的模型快照來(lái)檢測(cè)模型的更改(可以在團(tuán)隊(duì)環(huán)境中的 Code First 遷移中找到關(guān)于此的詳細(xì)信息)。 由于我們將假設(shè)數(shù)據(jù)庫(kù)已擁有當(dāng)前模型的架構(gòu),因此我們將生成一個(gè)空(無(wú)操作)遷移,該遷移將當(dāng)前模型作為快照。

  1. 在包管理器控制臺(tái)中運(yùn)行 Add-Migration InitialCreate –IgnoreChanges 命令。 這將創(chuàng)建一個(gè)以當(dāng)前模型作為快照的空遷移。
  2. 在包管理器控制臺(tái)運(yùn)行 Update-Database 命令。 這會(huì)將 InitialCreate 遷移應(yīng)用到數(shù)據(jù)庫(kù)。 由于實(shí)際遷移不包含任何更改,因此它只會(huì)向 __MigrationsHistory 表添加一行,指示已應(yīng)用此遷移。
  3. [圖片上傳失敗...(image-48a274-1668222314579)]

選項(xiàng)二:使用空數(shù)據(jù)庫(kù)作為起點(diǎn)

在這個(gè)場(chǎng)景中,我們需要遷移能夠從頭開(kāi)始創(chuàng)建整個(gè)數(shù)據(jù)庫(kù),包括本地?cái)?shù)據(jù)庫(kù)中已存在的表。 我們將生成一個(gè) InitialCreate 遷移,其中包含用于創(chuàng)建現(xiàn)有架構(gòu)的邏輯。 然后,我們將使現(xiàn)有數(shù)據(jù)庫(kù)看起來(lái)就像已應(yīng)用此遷移一樣。

  1. 在包管理器控制臺(tái)中運(yùn)行 Add-Migration InitialCreate 命令。 這將創(chuàng)建一個(gè)遷移以創(chuàng)建現(xiàn)有架構(gòu)。

[圖片上傳失敗...(image-104fb8-1668222314579)]
[圖片上傳失敗...(image-3cd56e-1668222314579)]

  1. 注釋掉新創(chuàng)建遷移的 Up 方法中的所有代碼。 這樣便可以將遷移“應(yīng)用”到本地?cái)?shù)據(jù)庫(kù),而無(wú)需嘗試重新創(chuàng)建所有已經(jīng)存在的表等。
  2. 在包管理器控制臺(tái)運(yùn)行 Update-Database 命令。 這會(huì)將 InitialCreate 遷移應(yīng)用到數(shù)據(jù)庫(kù)。 由于實(shí)際遷移不包含任何更改(因?yàn)橐褧簳r(shí)將其注釋掉),因此它只會(huì)向 __MigrationsHistory 表添加一行,指示已應(yīng)用此遷移。

[圖片上傳失敗...(image-40a36-1668222314579)]
[圖片上傳失敗...(image-dfa547-1668222314579)]

  1. 取消注釋 Up 方法中的代碼。 這意味著,當(dāng)此遷移應(yīng)用于將來(lái)的數(shù)據(jù)庫(kù)時(shí),本地?cái)?shù)據(jù)庫(kù)中已經(jīng)存在的架構(gòu)將由遷移創(chuàng)建。

EF6: 創(chuàng)建 mysql 遷移文件報(bào)錯(cuò)

未為提供程序“MySql.Data.MySqlClient”找到任何 MigrationSqlGenerator。請(qǐng)?jiān)谀繕?biāo)遷移配置類中使用 SetSqlGenerator 方法以注冊(cè)其他 SQL 生成器。
[圖片上傳失敗...(image-d44b9e-1668222314579)]
解決:
添加特性:
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]

關(guān)于注解的詳細(xì)使用:

https://learn.microsoft.com/zh-cn/ef/ef6/modeling/code-first/data-annotations

關(guān)于Mysql(EF6的支持)
https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework60.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容