.net core和efcore code first学习总结

项目改造建议:在将项目改成.net core之前,一定要先学习,不然很容易踩坑,导致项目进度变慢,.net core和asp.net mvc有很大区别
学习地址
https://docs.microsoft.com/zh-cn/aspnet/core/migration/mvc?view=aspnetcore-2.2
https://www.bilibili.com/video/av38392956/?p=8   强烈推荐
https://www.yuque.com/yuejiangliu/dotnet/solenovex-core-mvc-comp
https://www.cnblogs.com/chillsrc/p/10509412.html
https://ken.io/note/asp.net-core-tutorial-mvc-view-layout-section

 

项目发布到网站:

https://www.cnblogs.com/craigtaylor/p/11143484.html

https://www.cnblogs.com/humin/p/10330983.html

https://www.cnblogs.com/MrHSR/p/10374981.html#4444989 asp.net core系列 24 EF模型配置(主键,生成值,最大长度,并发标记)
快速开发技巧:
自动生成构造函数,在类下输入ctor+tab键按两下
方法里面参数自动生成属性,写完参数后,按ctrl+.,会弹出提示,然后选择后回车即可

在非div元素处鼠标右键,使用<div>换行,会在元素前后加上div标签

特别注意:.net core2.1中分组条件,必须使用new,不然单个字段分组时,不起作用,如entity.GroupBy(a => new { a.CategoryId }).Select<Xxx>

1、后台使用 HtmlEncoder.Default.Encode 防止恶意输入(即 JavaScript)损害应用
      防止重复提交常用办法:post-redirect-get,RedirectToAction(nameOf(Detail)),使用nameOf利于重构

2、项目安装mysql的ef支持
MySql.Data.EntityFrameworkCore、Microsoft.EntityFrameworkCore.Tools、Microsoft.EntityFrameworkCore.Proxies(延时加载)
使用Pomelo.EntityFrameworkCore.MySql替代MySql.Data.EntityFrameworkCore,因为efcore操作mysql时,出现错误System.InvalidOperationException:“No coercion operator is defined between types 'System.Int16' and 'System.Boolean'.”

Sql Server 请安装 Microsoft.EntityFrameworkCore.SqlServer

3、netcore项目支持依赖注入,nuget添加Microsoft.Extensions.DependencyInjection  https://stackoverflow.com/questions/32459670/resolving-instances-with-asp-net-core-di

4、efcore配置(配置 DbContext、连接字符串等)https://docs.microsoft.com/zh-cn/ef/core/miscellaneous/connection-strings

5、设置级联删除https://www.jianshu.com/p/39da9b023c81

6、目前针对dotnet core项目的nuget包,还不支持执行包里的代码模板和识别Content内容,所以暂时无法实现(不能通过nuget获取js库或者css第三方库,使用vs自带libman最方便)
      详情参考 https://docs.microsoft.com/zh-cn/nuget/create-packages/project-json-impact

     (6.1)、Bower 的安装,JS包默认安装到webroot的lib文件夹,可以通过.bowerrc文件更改安装路径(不推荐使用,会将很多无用的js和文件下载到项目中)
     https://blog.csdn.net/qq_33303204/article/details/81323512
     https://www.cnblogs.com/wanghaibin/p/9116816.html
     https://www.cnblogs.com/beginfromnow/p/6883747.html
     在安装 Bower 前,请安装它的以下依赖组件nodejs、git
     安装完成后打开 CMD 执行以下语句在全局中安装 Bower:npm install -g bower
     安装完成后可执行以下命令验证是否安装成功:bower -v
     在 Visual Studio 中建立 ASP.NET Core Web 应用程序。
     首先你可以看到依赖项内没有 Bower 管理,在项目右键也发现无管理 Bower 程序包选项。
     此时我们打开 CMD。切换到项目目录内(包含 *.csproj 的文件夹)。输入以下命令初始化 Bower (请不要使用 PowerShell ):
     bower init
     在vs项目下.bowerrc文件,配置外部工具中一定要去除$(VSInstalledExternalTools)或$(VSINSTALLDIR)\Web\External勾选,不然不能下载或更新文件到wwwroot/lib中

    (6.2)、使用LibMan添加依赖js和css库,强烈推荐使用此种方法添加js和css库
     https://docs.microsoft.com/zh-cn/aspnet/core/client-side/libman/libman-vs?view=aspnetcore-2.2
     https://blog.csdn.net/qq_22949043/article/details/86766808
     手动还原文件
     若要手动还原库文件:
     对于解决方案中的所有项目:
     右键单击解决方案的名称解决方案资源管理器。
     选择还原客户端库选项。
     对于特定的项目:
     右键单击libman.json中的文件解决方案资源管理器。
     选择还原客户端库选项。
     如果添加客户端库时选择提供程序为unpkg,必须输入完下载的框架后,然后@版本号才有提示
     添加jquery.validate.js等库,搜索使用jquery-validate、jquery-validation-unobtrusive

    (6.3)、配置使用npm文件安装目录node_modules像wwwroot目录一样可以使用静态文件
     在Startup.cs中加入如下代码
     app.UseStaticFiles(new StaticFileOptions
     { 
     RequestPath = "/node_modules",
     FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath,"/node_modules")) 
     });
     //使用<link href="~/node_modules/bootstrap/bootstrap.css">

7、efcore ef code first自动迁移,需要自动在数据库中新建表     

CREATE TABLE __EFMigrationsHistory
( 
MigrationId nvarchar(150) NOT NULL, 
ProductVersion nvarchar(32) NOT NULL, 
PRIMARY KEY (`MigrationId`) 
);
end;

 

8、ef core操作mysql 数据迁移需要导入Microsoft.EntityFrameworkCore.Design,版本是2.0.0;

https://www.cnblogs.com/whyd/p/9348325.html
https://www.cnblogs.com/Saumterer/p/7605340.html


9、ef code first一对多配置:https://blog.csdn.net/Fanbin168/article/details/81745861


10、执行数据库迁移命令时,提示不支持PowerShell 2.0版本(don't support PowerShell version 2.0. )解决
       https://www.bbsmax.com/A/6pdDBl6DJw 非常好
       https://www.cnblogs.com/systemnet123/p/10262096.html
       http://www.mamicode.com/info-detail-2584332.html

       Add-Migration Xxxx,每次增加或修改类后,都要重新执行此命令
      Update-Database -v 马上同步本地数据库,不适合正式环境
      当执行以上命令时,如果出现错误Build failed,选中项目解决方案-》右键-》重新生成解决方案,看下项目是否有报错的地方,当重新生成成功后,一般就可以执行了,如果还是不行,参考https://www.cnblogs.com/DHclly/p/11332591.html

11、Startup.cs取代Global.asax,Startup类负责处理所有应用程序启动任务
       BundleConfig.cs在asp.net core里面不存了,安装Bundler & Minifier工具替代
       要引用處理完的指令碼檔,在過去是使用 @Scripts.Render() 或 @Styles.Render() 將指令碼檔加入到網頁之中,現在只要在引用打包完後的指令碼檔時,加一個屬性叫 asp-append-version 的 TagHelper,把它設定為 true 就可以了。
       https://dotblogs.com.tw/supershowwei/2017/07/26/164153
       https://dotnetthoughts.net/bundling-and-minification-in-aspnet-core/
       https://marketplace.visualstudio.com/items?itemName=MadsKristensen.BundlerMinifier
       https://www.cnblogs.com/yunspider/p/9746555.html

12、Razor指令可以根据规则从 HTML 转换为 C# 或 Razor 特定标记。 当在 @ 符号后跟 Razor 保留关键字时,它会转换为 Razor 特定标记,如果不是Razor保留关键字,则会转换为 C#。
       @page Razor 指令将文件转换为一个 MVC 操作,这意味着它可以处理请求。 @page 必须是页面上的第一个 Razor 指令。 @page 是转换成 Razor 特定标记的一个示例。

13、mvc模板页使用:@RenderSection("header", false)

       @RenderBody()
       @RenderSection("Scripts", required: false)//required: false表示不是必须的
       子页面:@section header
       {}
       @section Scripts {
       @{
       await Html.RenderPartialAsync("_ValidationScriptsPartial");}
       }
       https://ken.io/note/asp.net-core-tutorial-mvc-view-layout-section


14、页面文件介绍
_layout.cshtml文件中包含通用的HTML元素(脚本和样式表)和应用程序的总体布局。例如,当你点击RazorMvcBooks,Home,About的链接时,你会看到同样的页眉与页脚布局。
_viewstart.cshtml文件当作_layout.cshtml文件的布局属性来使用。可以放公用html
_viewimports.cshtml包含导入到每个Razor页面的Razor指令。
_validationscriptspartial.cshtml文件提供对jQuery验证脚本的引用。当我们添加创建和编辑网页时,_validationscriptspartial.cshtml文件将被使用。
@Html.PartialAsync("_PartialViewName",data):复用View代码,@Html.Partial()未旧方法或使用
使用<partial name="_StudentRow" for="@s">替换@Html.Partial
@await Commponent.InvokeAsync("XXX"):可复用、独立组件、有独立的逻辑/数据、相当于迷你mvc请求、不依赖于父级View的数据,通常放到ViewComponents文件夹下
taghelper对于写法<vc:welcome></vc:welcome>,必须在_ViewImports.cshtml导入当前项目命名空间才能使用

15、@Html.使用TagHelper替代,Tag helpers是服务器端的C#代码,它在Razor文件里,它会参与到创建和渲染HTML元素的过程。
asp-开头都是taghelper,asp-action、asp-controller、asp-route-id、asp-route-name、asp-for、asp-items、asp-validation-for
_ViewImports.cshtml
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<select asp-for="Gender" asp-items="Html.GetEnumSelectList<Gender>()"></select>
<span asp-validation-for="birthdate"></span>
<span asp-validation-summary="All"></span> 模型错误汇总显示
<span asp-validation-summary="ModelOnly"></span> ModelState.AddModelError()添加的错误才会显示
15.1、JavaScript TagHelpers
asp-src-include:导入指定目录下的所有js文件,<script asp-src-include="~app/**/*.js" asp-src-exclude="~app/services/**/*.js">
asp-src-exclude:排除指定目录下的所有js文件
asp-fallback-src:使用cdn导入js如果失败,则使用此本地地址文件
asp-fallback-test:测试cdn的js是否引入成功
15.2、Css TagHelpers
asp-fallback-href:使用cdn导入css如果失败,则使用此本地地址文件
asp-fallback-test-class:测试cdn文件中是否存在指定类选择器
asp-fallback-test-property:测试cdn文件中是否存在指定属性
asp-fallback-test-value:测试cdn文件中指定属性是否存在指定值

15.3、asp-append-version:版本号,追加文件Hash值,通常和src一起使用

15.4、自定义元素TagHelper,新建类,类名以TagHelper结尾,继承TagHelper,重写Process方法
自定义TagHelper要在_ViewImport.cshtml中导入,如@addTagHelper *,Heavy.Web

 使用TagHelper:<email mail-to="123@qq.com">support</email>

15.5、自定义属性TagHelper
<bold color="green">加粗字体<bold>
<p bold color="red">加粗字体</p>

 15.6、自定义类属性TagHelper

 使用自定义类TagHelper:

 15.7、属性条件TagHelper

 

 使用条件TagHelper

 15.8、TagHelper前缀,可以页面中指定前缀的元素,TagHelper才生效
@tagHelperPrefix "my:"

 

 

16、获取控制器和action名称
this.ControllerContext.ActionDescriptor.ControllerName
this.ControllerContext.ActionDescriptor.ActionName

17、.net core Identity用户登录使用
核心对象UserManager<IdentityUser>、SignInManager<IdentityUser>、RoleManager<IdentityRole>
使用在Startup.cs中配置
string connectionString = Configuration.GetConnectionString("MysqlConnection");
//注册数据库上下文
services.AddDbContext<Data.NBSharpDbContext>(options => options.UseMySql(connectionString));
//注册Identity
services.AddDbContext<IdentityDbContext>(options => options.UseMySql(connectionString));
services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 1;
}).AddEntityFrameworkStores<IdentityDbContext>();
app.UseAuthentication();//全局身份认证,必须放在app.UseMvc()之前
执行数据库迁移Add-migration InitIdentity -Context IdentityDbContext
//页面中判断是否登录@if(SignInManager.IsSignedIn(User)){...}
//Controller用户登录才能访问,再Controller或Action上加上[Authorize]即可

 

18、页面中使用注入对象@inject SignInManager<IdentityUser> SignInManager
    SignInManager为变量名

19、mvp提供增删改查参考https://github.com/solenovex/ASP.NET-Core-MVC-Tutorial-Code
RoleController AddUserToRole()中代码应该调整为
// 使用SQL语句的方式实现
// 方法一、推荐,先查所有用户,再查角色的用户,然后在内存中排除
// 所有用户
var users = await _userManager.Users*************);
// 当前角色包含的用户
var users2 = await _userManager.Users.FromSql(
"select u.* from AspNetUsers u, AspNetUserRoles r where u.Id = r.UserId and r.RoleId = @roleId ",
new SqlParameter("@roleId", roleId))*************);
// 添加当前角色不包含的用户
vm.Users.AddRange(users.Where(u => users2.Contains(u) == false));
// 方法二、不推荐,直接使用 not in语句
//vm.Users.AddRange(await _userManager.Users.FromSql(
// "select u.* from AspNetUsers u where u.Id not in (select UserId from AspNetUserRoles where RoleId = {0})",
// roleId)*************));

20、.net-core的api接口不再返回HttpResponseMessage,返回和mvc控制层一样、可以是JsonResult、void、string等待

21、.net-core里面使用HttpContext对象
      

public class xxxAppService : PlatformAppService
{
    private readonly IHttpContextAccessor httpContextAccessor;
 
    public xxxAppService(IHttpContextAccessor _httpContextAccessor)
    {
        httpContextAccessor = _httpContextAccessor;
    }
 
    public async Task<string> GetHeaders()
    {
        var headers = httpContextAccessor.HttpContext.Request.Headers;
 
        return headers["Authorization"];
    }
}

22、.netcore中使用HttpContext对象  https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-context?view=aspnetcore-2.2 

23、.netcore执行sql查询 语句https://docs.microsoft.com/zh-cn/ef/core/querying/raw-sql

        默认生成的为Person的Model,如果Select获取的字段中不包含Person中的某字段就会抛异常了,例如:下面的语句只获取name字段,并没有包含Person的其他字段,那么抛异常:The required column 'id' was not present in the results of a 'FromSql' operation.

db.Set<Person>().FromSql($"select name from {nameof(Person)} ").ToList();
那么改为:
db.Set<Person>().Select(l => l.name).FromSql($"select name from {nameof(Person)} ").ToList();

 24、View Component
显示部分内容、Mini Controller、可复用、只能配合父级View使用
实现ViewComponent

 使用ViewComponent,新建文件夹:Components/InternetStatus/Default.cshtml(可放到Shared文件夹下,全局通用)

 

 具体页面中使用此ViewComponent@await Component.InvokeAsync("InternetStatus")

 25、诊断中间件UseDeveloperExceptionPage、UseStatusCodePages、UseExceptionHandler、UseWelcomePage

 

39、悲观并发控制和乐观并发控制

悲观并发控制:

(1)、悲观并发控制一般采用行锁、表锁等排他锁对资源进行锁定,确保同时只有一个使用者操作被锁定的资源。

(2)、EF Core没有封装悲观并发控制的使用,需要开发人员编写原生SQL语句来使用悲观并发控制。不同数据库的语法不一样。

(3)、锁是独占、排他的,如果系统并发量很大的话,会严重影响性能,如果使用不当的话,甚至会导致死锁。

(4)、不同数据库的语法不一样。

锁是和事务相关的,因此通过BeginTransactionAsync()创建一个事务,并且在所有操作完成后调用CommitAsync()提交事务。

var h1 = await ctx.Houses.FromSqlInterpolated($"select * from T_Houses where Id=1 for update").SingleAsync();

乐观并发控制:

乐观并发控制的原理

Update T_Houses set Owner=新值 where Id=1 and Owner=旧值 举例子。当Update的时候,如果数据库中的Owner值已经被其他操作者更新为其他值了,那么where语句的值就会为false,因此这个Update语句影响的行数就是0,EF Core就知道“发生并发冲突”了,因此SaveChanges()方法就会抛出DbUpdateConcurrencyException异常。

以下适用于表只有一列并发控制

(1)、把被并发修改的属性使用IsConcurrencyToken()设置为并发令牌。

(2)、builder.Property(h => h.Owner).IsConcurrencyToken();

(3)、catch(DbUpdateConcurrencyException ex) {

var entry = ex.Entries.First();

var dbValues = await entry.GetDatabaseValuesAsync();

string newOwner = dbValues.GetValue<string>(nameof(House.Owner));

Console.WriteLine($"并发冲突,被{newOwner}提前抢走了");

}

通过rowversion解决表有多列需要并发控制

class House
{
    public long Id { get; set; }
    public string Name { get; set; }
    public string Owner { get; set; }
    public byte[] RowVer { get; set; }
}
builder.Property(h => h.RowVer).IsRowVersion();

 

1、乐观并发控制能够避免悲观锁带来的性能、死锁等问题,因此推荐使用乐观并发控制而不是悲观锁。

2、如果有一个确定的字段要被进行并发控制,那么使用IsConcurrencyToken()把这个字段设置为并发令牌即可;

3、如果无法确定一个唯一的并发令牌列,那么就可以引入一个额外的属性设置为并发令牌,并且在每次更新数据的时候,手动更新这一列的值。如果用的是SQLServer数据库,那么也可以采用RowVersion列,这样就不用开发者手动来在每次更新数据的时候,手动更新并发令牌的值了。

 

 

40、FluentValidation

1、FluentValidation:用类似于EF Core中Fluent API的方式进行校验规则的配置,也就是我们可以把对模型类的校验放到单独的校验类中。

2、 FluentValidation在ASP.NET Core项目中的用法

1)NuGet:FluentValidation.AspNetCore

2)builder.Services.AddFluentValidation(fv => { Assembly assembly = Assembly.GetExecutingAssembly();

fv.RegisterValidatorsFromAssembly(assembly);// RegisterValidatorsFromAssemblies });

3)编写模型类Login2Request public record Login2Request(string Email, string Password, string Password2);

4)编写继承自AbstractValidator的数据校验类

public class Login2RequestValidator: AbstractValidator<Login2Request> {

    public Login2RequestValidator() {

        RuleFor(x=>x.Email).NotNull().EmailAddress() .Must(v=>v.EndsWith("@qq.com")||v.EndsWith("@163.com")) .WithMessage("只支持QQ和163邮箱");

        RuleFor(x => x.Password).NotNull().Length(3, 10) .WithMessage("密码长度必须介于3到10之间") .Equal(x => x.Password2).WithMessage("两次密码必须一致");

    }

}

5)用Login2Request做Action方法的参数。

调用数据库服务

1、可以通过构造方法来向数据校验类中注入服务

2、RuleFor(x => x.UserName).NotNull() .Must(name=>dbCtx.Users.Any(u=>u.UserName== name)) .WithMessage(c => $"用户名{c.UserName}不存在");

3、RuleFor(x => x.UserName).NotNull() .MustAsync((name,_) => dbCtx.Users.AnyAsync(u => u.UserName == name)) .WithMessage(c => $"用户名{c.UserName}不存在");

 本地化多语言 https://www.cnblogs.com/mq0036/p/14548370.html

FluentValidation 为默认验证消息提供几种语言的翻译,默认情况下, 会根据当前线程的 CurrentUICulture 语言文化来选择语言,你也可以使用 WithMessage 和 WithLocalizedMessage 来指定错误提示。

WithMessage

如果使用 Visual Studio 的内置的 resx 格式资源文件, 则可以通过调用 WithMessage 本地化错误消息。

RuleFor(x => x.Surname).NotNull().WithMessage(x => MyLocalizedMessages.SurnameRequired);

当然,您可以将多种语言存储在数据库中,通过 lambda 表达式来读取多语言消息。

WithLocalizedMessage

您可以通过调用 WithLocalizedMessage 方法,传递资源类型和资源名称,使错误消息支持本地多语言。

RuleFor(x => x.Surname).NotNull().WithLocalizedMessage(typeof(MyLocalizedMessages), "SurnameRequired");

 

41、 REST的优点

1、通过URL对资源定位,语义更清晰; 2、通过HTTP谓词表示不同的操作,接口自描述; 3、可以对GET、PUT、DELETE请求进行重试; 4、可以用GET请求做缓存; 5、通过HTTP状态码反映服务器端的处理结果,统一错误处理机制。 6、网关等可以分析请求处理结果。

REST的缺点

1、真实系统中的资源非常复杂,很难清晰地进行资源的划分,对技术人员的业务和技术水平要求高。 2、不是所有的操作都能简单地对应到确定的HTTP谓词中。 3、系统的进化可能会改变幂等性。 4、通过URL进行资源定位不符合中文用户的习惯。 5、HTTP状态码个数有限。 6、有些环节会篡改非200响应码的响应报文。 7、有的客户端不支持PUT、DELETE请求。

 

42、依赖注入性能消耗很高的特殊服务,可以通过action注入

public class TestService
{
    private string[] files;
    public TestService()
    {
    this.files=Directory.GetFiles("D:/Program Files","*.exe",SearchOption.AllDirectories);
    }

    public int Count{get{return this.files.Length;}}
}
[HttpGet]
public int Test1([FromServices]TestService testService,int x)
{
    return testService.Count+x;
}

 

 43、同步方法中调用异步方法Main(args).GetAwaiter().GetResult();

 

44、异步编程
如果想在异步方法中暂停一段时间,不要用Thread.Sleep(),因为它会堵塞调用线程,而要用await Task.Delay();

有时需要提前终止任务,比如:请求超时、用户取消请求。 很多异步方法都有CancellationToken参数,用于获得提前终止执行的信号 

CancellationToken结构体 None:空 bool IsCancellationRequested 是否取消 (*)Register(Action callback) 注册取消监听 ThrowIfCancellationRequested() 如果任务被取消,执行到这句话就抛异常。

CancellationTokenSource CancelAfter()超时后发出取消信号 Cancel() 发出取消信号

ASP.NET Core开发中,一般不需要自己处理CancellationToken、CancellationTokenSource这些,只要做到“能转发CancellationToken就转发”即可。ASP.NET Core会对于用户请求中断进行处理。

public async Task<IActionResult> Index(CancellationToken cancellationToken)
{
    await DownloadAsync("https://www.baidu.com",100,cancellationToken);
    return View();
}

 

static async Task DownloadAsync(string url, int n, CancellationToken cancellationToken)
{
    using (HttpClient client = new HttpClient())
    {
        for (int i = 0; i < n; i++)
        {
            string html = await client.GetStringAsync(url);
            Console.WriteLine($"{DateTime.Now}:{html}");
            if (cancellationToken.IsCancellationRequested)
            {
                Console.WriteLine("请求被取消");
                break;
            }
            //cancellationToken.ThrowIfCancellationRequested();//取消抛出异常
        }
    }
}
static async Task Download2Async(string url, int n, CancellationToken cancellationToken)
{
    using (HttpClient client = new HttpClient())
    {
        for (int i = 0; i < n; i++)
        {
            var resp = await client.GetAsync(url, cancellationToken);
            string html = await resp.Content.ReadAsStringAsync();
            Console.WriteLine($"{DateTime.Now}:{html}");
        }
    }
}

static async Task Main(string[] args)
{
    //CancellationTokenSource cts = new CancellationTokenSource();
    //cts.CancelAfter(5000);
    //CancellationToken cToken = cts.Token;
    //await DownloadAsync("https://www.baidu.com", 100, cToken);

    CancellationTokenSource cts = new CancellationTokenSource();
    CancellationToken cToken = cts.Token;
    DownloadAsync("https://www.baidu.com", 200, cToken);
    while (Console.ReadLine() != "c")
    {

    }
    cts.Cancel();
    Console.ReadLine();
}

 

Task类的重要方法:

1. Task<Task> WhenAny(IEnumerable<Task> tasks)等,任何一个Task完成,Task就完成

2. Task<TResult[]> WhenAll<TResult>(params Task<TResult>[] tasks)等,所有Task完成,Task才完成。用于等待多个任务执行结束,但是不在乎它们的执行顺序。

3. FromResult() 创建普通数值的Task对象。

 

45、Linq中Single和First区别

Single:有且只有一条满足要求的数据;如果序列中没有一条数据,会报错,有多条数据,也会报错

SingleOrDefault:最多只有一条满足要求的数据;

First :至少有一条,返回第一条;如果序列中没有一条数据,会报错,有多条返回第一条数据,不会报错

FirstOrDefault:返回第一条或者默认值;

 

46、读取配置文件

原始读取方式:

NuGet安装Microsoft.Extensions.Configuration和Microsoft.Extensions.Configuration.Json

ConfigurationBuilder configBuilder = new ConfigurationBuilder();

configBuilder.AddJsonFile( "config.json", optional: false, reloadOnChange: false);

IConfigurationRoot config = configBuilder.Build();

string name = config["name"];

string proxyAddress = config.GetSection("proxy:address").Value;

optional参数表示这个文件是否可选。初学时,建议optional设置为false,这样写错了的话能够及时发现。

reloadOnChange参数表示如果文件修改了,是否重新加载配置

1、可以绑定一个类,自动完成配置的读取。

2、NuGet安装:Microsoft.Extensions.Configuration.Binder

3、Server server = configRoot.GetSection("proxy").Get<类名>();

 推荐读取方式:

NuGet再安装:Microsoft.Extensions.Options

读取配置的时候,DI要声明IOptions<T>、IOptionsMonitor<T>、IOptionsSnapshot<T>等类型。IOptions<T>不会读取到新的值;和IOptionsMonitor 相比, IOptionsSnapshot会在同一个范围内(比如ASP.NET Core一个http请求中)保持一致。建议用IOptionsSnapshot

1、在读取配置的地方,用IOptionsSnapshot<T>注入。不要在构造函数里直接读取IOptionsSnapshot.Value,而是到用到的地方再读取,否则就无法更新变化。

2、如下配置 services.AddOptions() .Configure<DbSettings>(e => config.GetSection("DB").Bind(e)) .Configure<SmtpSettings>(e => config.GetSection("Smtp").Bind(e));

services.AddTransient<Demo>();//不能用Singleton

 

 ef core中使用Like EF.Functions.Like(c.Boss, "%Jeremy%")

.net core项目重命名后错误解决:

错误 NETSDK1007 找不到“E:\Project\MyProject\MyProject.Common\MyProject.Utility.csproj”的项目信息。这可以指示缺少一个项目引用。 MyProject.Data C:\Program Files\dotnet\sdk\2.2.107\Sdks\Microsoft.NET.Sdk\targets\Microsof

 

.Net Core 3.1 解决数据大小限制

 

posted @ 2019-08-18 21:37  事理  阅读(1164)  评论(0编辑  收藏  举报