国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

.NET-4.ORM 常見框架EFcorn、Dapper、SqlSugar、FreeSql 和ADO.NET

這篇具有很好參考價值的文章主要介紹了.NET-4.ORM 常見框架EFcorn、Dapper、SqlSugar、FreeSql 和ADO.NET。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


前言

學(xué)習參考:
1. .NET 6教程,.Net Core 2022視頻教程,楊中科主講— 以及資料參考
2. 官方文檔EF core
常用的語句
3..netmvc
https://www.cnblogs.com/1016391912pm/p/12024671.html
https://github.com/dotnet/EntityFramework.Docs/tree/main/samples/core/Querying/Overview
第一個EFCore應(yīng)用
https://docs.microsoft.com/zh-cn/ef/core/modeling/entity-types?tabs=fluent-api

//添加包
Microsoft.EntityFrameworkCore.Sqlite
Pomelo.EntityFrameworkCore.MySql
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Tools
Add-Migration InitialCreate//實現(xiàn)遷移
Update-database//生成數(shù)據(jù)庫
Update-Database InitialCreate
Remove-migration//刪除最后一次的遷移腳本
Script-Migration//生成遷移SQL代碼
Script-Migration D F//生成版本D到版本F的SQL腳本
Script-Migration D//生成版本D到最新版本的SQL腳本:

dotnet add package Microsoft.EntityFrameworkCore.Design//添加 EF Core 工具所需的包。
dotnet tool install --global dotnet-ef//將安裝 dotnet ef,用于創(chuàng)建遷移和基架的工具。
dotnet ef migrations add InitialCreate --context PizzaContext//創(chuàng)建數(shù)據(jù)庫的遷移
dotnet ef database update --context PizzaContext//將應(yīng)用遷移生成數(shù)據(jù)庫。

builder.Services.AddSqlite<PizzaContext>("Data Source=ContosoPizza.db");

什么是ORM

(Object Relational Mapping關(guān)系對象映射)
讓開發(fā)者用對象操作的形式操作關(guān)系數(shù)據(jù)庫。
.net 常用的orm:EF coreDapper、SqlSugar、FreeSql

EF Core學(xué)習與深入

一、了解 EF Core

1、Entity Framework Core(EF Core)是微軟官方的ORM框架。優(yōu)點:功能強大、官方支持、生產(chǎn)效率高、力求屏蔽底層數(shù)據(jù)庫差異;缺點:復(fù)雜、上手門檻高、不熟悉EFCore的話可能會進坑。
2、Dapper。優(yōu)點:簡單,N分鐘即可上手,行為可預(yù)期性強;缺點:生產(chǎn)效率低,需要處理底層數(shù)據(jù)庫差異。
3、EF Core是模型驅(qū)動(Model-Driven)的開發(fā)思想,Dapper是數(shù)據(jù)庫驅(qū)動(DataBase-Driven)的開發(fā)思想的。沒有優(yōu)劣,只有比較。
4、性能: Dapper等≠性能高;EF Core≠性能差。
5、EF Core是官方推薦、推進的框架,盡量屏蔽底層數(shù)據(jù)庫差異,.NET開發(fā)者必須熟悉,根據(jù)的項目情況再決定用哪個。

對于后臺系統(tǒng)、信息系統(tǒng)等和數(shù)據(jù)庫相關(guān)開發(fā)工作量大的系統(tǒng),且團隊比較穩(wěn)定,用EF Core;對于互聯(lián)網(wǎng)系統(tǒng)等數(shù)據(jù)庫相關(guān)工作量不大的系統(tǒng),或者團隊不穩(wěn)定,用Dapper。

1.DbContext

EF中的上下文(DbContext)簡介
DbContext是實體類和數(shù)據(jù)庫之間的橋梁,DbContext主要負責與數(shù)據(jù)交互,主要作用:

1、DbContext包含所有的實體映射到數(shù)據(jù)庫表的實體集(DbSet < TEntity >)。
2、DbContext 將LINQ-to-Entities查詢轉(zhuǎn)換為SQL查詢并將其發(fā)到數(shù)據(jù)庫。
3、更改跟蹤: 它跟蹤每個實體從數(shù)據(jù)庫中查詢出來后發(fā)生的修改變化。
4、持久化數(shù)據(jù): 它也基于實體狀態(tài)執(zhí)行插入、更新和刪除操作到數(shù)據(jù)庫中

DbContext類是EntityFramework (簡稱 EF)中的一個類,可以理解為一個數(shù)據(jù)庫對象的實例。在 EF中,無需手動的拼接 SQL 語句對數(shù)據(jù)庫進行增刪改查,而是通過 DbContext 來進行相應(yīng)操作。

2.數(shù)據(jù)注釋、Fluent API學(xué)習

https://docs.microsoft.com/zh-cn/ef/core/modeling/entity-types?tabs=fluent-api

1、視圖與實體類映射:modelBuilder.Entity<Blog>().ToView("blogsView");
2、排除屬性映射:
modelBuilder.Entity<Blog>().Ignore(b => b. Name2);
3、配置列名:
modelBuilder.Entity<Blog>().Property(b =>b.BlogId).HasColumnName("blog_id");
4、配置列數(shù)據(jù)類型:
builder.Property(e => e.Title) .HasColumnType("varchar(200)")
5、配置主鍵
默認把名字為Id或者“實體類型+Id“的屬性作為主鍵,可以用HasKey()來配置其他屬性作為主鍵。modelBuilder.Entity<Student>().HasKey(c => c.Number);
支持復(fù)合主鍵,但是不建議使用。
6、生成列的值
modelBuilder.Entity<Student>().Property(b => b.Number).ValueGeneratedOnAdd();
7、可以用HasDefaultValue()為屬性設(shè)定默認值
modelBuilder.Entity<Student>().Property(b => b.Age).HasDefaultValue(6);
8、索引
modelBuilder.Entity<Blog>().HasIndex(b => b.Url);
復(fù)合索引
modelBuilder.Entity<Person>().HasIndex(p => new { p.FirstName, p.LastName });
唯一索引:IsUnique();聚集索引:IsClustered()
9...  用EF Core太多高級特性的時候謹慎,盡量不要和業(yè)務(wù)邏輯混合在一起,以免“不能自拔”。比如Ignore、Shadow、Table Splitting等……
## ef core
//模型聲明Blogs、AuditEntry、Post
internal class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<AuditEntry>();
    }
}

# 從模型中排除類型
[NotMapped]
public class BlogMetadata
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    [NotMapped]//排除屬性
    public DateTime LoadedFromDatabase { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Ignore<BlogMetadata>();
   // modelBuilder.Entity<BlogMetadata>()
   //     .Ignore(b => b.LoadedFromDatabase);
}

# 表名稱、表架構(gòu)、表注釋
按照約定,每個實體類型都將設(shè)置為映射到與公開實體的 DbSet 屬性名稱相同的數(shù)據(jù)庫表。 如果給定實體不存在 DbSet,則使用類名稱。
[Table("blogs", Schema = "blogging")]
[Comment("Blogs managed on the website")]//表注釋
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .ToTable("blogs");
   // modelBuilder.Entity<Blog>()
   //     .ToTable("blogs", schema: "blogging");
   modelBuilder.Entity<Blog>()
        .HasComment("Blogs managed on the website");
}
# 模型的數(shù)據(jù)注釋和FluentAPI的屬性定義
.HasKey(c => c.LicensePlate);[Key]//主鍵
.HasName("PrimaryKey_BlogId");//主鍵名
.Ignore(b => b.LoadedFromDatabase);[NotMapped]//排除類型

HasColumnName("blog_id");[Column("blog_id")]//列名
HasColumnType("varchar(200)");[Column(TypeName = "varchar(200)")]//列數(shù)據(jù)類型
HasMaxLength(500);[MaxLength(500)]//最大長度
HasPrecision(14, 2);[Precision(14, 2)]//屬性配置為精度為 14 和小數(shù)位數(shù)為 2
IsUnicode(false);[Unicode(false)]//Unicode
IsRequired();[Required]//必須屬性
.HasComment();[Comment("Blogs managed on the website")]//列注釋
.HasColumnOrder(0);[Column(Order = 0)]//列順序
.HasDefaultValue(3);//默認值
.HasDefaultValueSql("getdate()");//默認值

public class Blog
{
    [Column("blog_id")]
    [MaxLength(500)]
    public int BlogId { get; set; }

    [Column(TypeName = "varchar(200)")]
    public string Url { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.BlogId)
        .HasColumnName("blog_id");

    modelBuilder.Entity<Blog>(
        eb =>
        {
            eb.Property(b => b.Url).HasColumnType("varchar(200)");
            eb.Property(b => b.Rating).HasColumnType("decimal(5, 2)");
        });
}
# 分組配置
public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
{
    public void Configure(EntityTypeBuilder<Blog> builder)
    {
        builder
            .Property(b => b.Url)
            .IsRequired();
    }
}

new BlogEntityTypeConfiguration().Configure(modelBuilder.Entity<Blog>());



# 查詢數(shù)據(jù)  關(guān)聯(lián)查詢Include
支持的操作包括:Where、OrderBy、OrderByDescending、ThenBy、ThenByDescending、Skip 和 Take。
var blogs = context.Blogs.ToList();//加載所有數(shù)據(jù)
.Include(blog => blog.Posts).ToList();//Posts所有數(shù)據(jù)
.Single(b => b.BlogId == 1);//加載單個實體
.SingleOrDefault(b => b.BlogId == 1);//
.Where(b => b.Url.Contains("dotnet")).ToList();//篩選
.OrderByDescending(blog => blog.Rating).Select(
        blog => new { Id = blog.BlogId, Url = StandardizeUrl(blog.Url) })
    .ToList();排序
.Include(
            blog => blog.Posts
                .Where(post => post.BlogId == 1)
                .OrderByDescending(post => post.Title)
                .Take(5))
        .ToList();
context.Blogs.Add(blog);//添加數(shù)據(jù)
context.Blogs.Remove(blog);//刪除數(shù)據(jù)
context.SaveChanges();//保存

二、簡單的案例使用1(推薦參考最佳)

第一個EFCore應(yīng)用

連接mysql(Pomelo.EntityFrameworkCore.MySql)
string connection = “server=127.0.0.1;userid=root;pwd=123456;port=3306;database=blogging;sslmode=none;Convert Zero Datetime=True”;//
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseMySql(connection, new MySqlServerVersion(new System.Version(5, 7, 37)));

1.創(chuàng)建一個控制臺程序
2.添加包
Microsoft.EntityFrameworkCore.Sqlite
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Tools
3.增加model類Model.cs //是一對多的
public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
    public string DbPath { get; }
    public BloggingContext()
    {
        var folder = Environment.SpecialFolder.LocalApplicationData;
        var path = Environment.GetFolderPath(folder);//
        DbPath = System.IO.Path.Join(path, "blogging.db");
    }

    // The following configures EF to create a Sqlite database file in the
    // special "local" folder for your platform.
    protected override void OnConfiguring(DbContextOptionsBuilder options)
        => options.UseSqlite($"Data Source={DbPath}");
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    
    public List<Post> Posts { get; } = new();
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

4.在程序包管理器控制臺
Add-Migration FirstMigration
Update-Database

5.Program.cs(進行CRUD)
using (var db = new BloggingContext())
{
    // Note: dababase path
    Console.WriteLine($"Database path: {db.DbPath}.");

    //Create
    //Console.WriteLine("Inserting a new blog");
    //db.Add(new Blog { Url = "http://baidu.com" });//http://blogs.msdn.com/adonet;
    //db.SaveChanges();

    // Read
    Console.WriteLine("Querying for a blog");
    var blog = db.Blogs
        .OrderBy(b => b.BlogId)
        .FirstOrDefault();
    //var blogs = db.Blogs.Where(b => b.BlogId > 1);
    //foreach (var item in blogs)
    //{
    //    Console.WriteLine($"{item.Url}");
    //}

    // Update
    Console.WriteLine("Updating the blog and adding a post");
    blog!.Url = "https://devblogs.microsoft.com/dotnet";
    blog.Posts.Add(
        new Post { Title = "Hello World", Content = "I wrote an app using EF Core!" });
    db.SaveChanges();

     Delete
    Console.WriteLine("Delete the blog");
    db.Remove(blog);
    db.SaveChanges();
}

三、簡單的案例使用2

命令行

//需要添加所需的包
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.Design//添加 EF Core 工具所需的包。
dotnet tool install --global dotnet-ef//將安裝 dotnet ef,用于創(chuàng)建遷移和基架的工具。

dotnet ef migrations add InitialCreate --context PizzaContext//創(chuàng)建數(shù)據(jù)庫的遷移
dotnet ef database update --context PizzaContext//將應(yīng)用遷移生成數(shù)據(jù)庫。
  1. 在項目根目錄中,添加一個名為 Data 的新文件夾。
  2. 在 Data 目錄中,創(chuàng)建一個名為 PizzaContext.cs 的新文件。 將以下代碼添加到空文件中:
  3. 在 Program.cs 中,將 // Add the PizzaContext
using Microsoft.EntityFrameworkCore;
using ContosoPizza.Models;

namespace ContosoPizza.Data;

public class PizzaContext : DbContext
{
    public PizzaContext (DbContextOptions<PizzaContext> options)
        : base(options)
    {
    }

    public DbSet<Pizza> Pizzas => Set<Pizza>();//表名
    public DbSet<Topping> Toppings => Set<Topping>();
    public DbSet<Sauce> Sauces => Set<Sauce>();
}

//-------------------
builder.Services.AddSqlite<PizzaContext>("Data Source=ContosoPizza.db");

四、簡單的案例使用3

兩種配置方式

1、Data Annotation
把配置以特性(Annotation)的形式標注在實體類中。
[Table(“T_Books”)]
public class Book
{
}
優(yōu)點:簡單;缺點:耦合。
2、Fluent API
builder.ToTable(“T_Books”);
把配置寫到單獨的配置類中。
缺點:復(fù)雜;優(yōu)點:解耦

Guid主鍵
1、 Guid算法(或UUID算法)生成一個全局唯一的Id。適合于分布式系統(tǒng),在進行多數(shù)據(jù)庫數(shù)據(jù)合并的時候很簡單。優(yōu)點:簡單,高并發(fā),全局唯一;缺點:磁盤空間占用大。

yzk開源的高效批量修改、刪除的開源項目Zack.EFCore.Batch
1、經(jīng)典步驟:建實體類;建DbContext;生成數(shù)據(jù)庫;編寫調(diào)用EF Core的業(yè)務(wù)代碼。

程序包管理器控制臺
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Pomelo.EntityFrameworkCore.MySql
optionsBuilder.UseMySql("server=localhost;user=root;password=root;database=ef",
	new MySqlServerVersion(new Version(5, 6, 0)));
Install-Package Npgsql.EntityFrameworkCore.PostgreSQL
optionsBuilder.UseNpgsql("Host=127.0.0.1;Database=ef;Username=postgres;Password=123456");

.NET-4.ORM 常見框架EFcorn、Dapper、SqlSugar、FreeSql 和ADO.NET

//Book.cs
public class Book
{
     public long Id { get; set; }//主鍵
    [Required]
    [MaxLength(100)]
     public string Title { get; set; }//標題
     public DateTime PubTime { get; set; }//發(fā)布日期
     public double Price { get; set; }//單價
 }
 //創(chuàng)建實現(xiàn)了IEntityTypeConfiguration接口的實體配置類,配置實體類和數(shù)據(jù)庫表的對應(yīng)關(guān)系
class BookEntityConfig : IEntityTypeConfiguration<Book>
{
	public void Configure(EntityTypeBuilder<Book> builder)
	{
		builder.ToTable("T_Books");
		//builder.Property(e => e.Title).HasMaxLength(50).IsRequired();
		//builder.Property(e => e.AuthorName).HasMaxLength(20).IsRequired();
	}
}
//創(chuàng)建繼承自DbContext的類
class TestDbContext:DbContext
{
	public DbSet<Book> Books { get; set; }
	protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
	{
		string connStr = "Server=.;Database=demo1;Trusted_Connection=True;MultipleActiveResultSets=true";
		optionsBuilder.UseSqlServer(connStr);
	}
	protected override void OnModelCreating(ModelBuilder modelBuilder)
	{
		base.OnModelCreating(modelBuilder);
		modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
	}
}
//插入數(shù)據(jù)
//只要操作Books屬性,就可以向數(shù)據(jù)庫中增加數(shù)據(jù),但是通過C#代碼修改Books中的數(shù)據(jù)只是修改了內(nèi)存中的數(shù)據(jù)。對Books做修改后,需要調(diào)用DbContext的異步方法SaveChangesAsync()把修改保存到數(shù)據(jù)庫。也有同步的保存方法SaveChanges(),但是用EF Core都推薦用異步方法。
//查詢數(shù)據(jù)
1、DbSet實現(xiàn)了IEnumerable<T>接口,因此可以對DbSet實施Linq操作來進行數(shù)據(jù)查詢。EF Core會把Linq操作轉(zhuǎn)換為SQL語句。面向?qū)ο?,而不是面向?shù)據(jù)庫(SQL)2、ctx.Books.Where(b => b.Price > 80)
Book b1 = ctx.Books.Single(b => b.Title== "零基礎(chǔ)趣學(xué)C語言");
Book b2 = ctx.Books.FirstOrDefault(b=>b.Id==9);
3、可以使用OrderBy操作進行數(shù)據(jù)的排序
IEnumerable<Book> books = ctx.Books.OrderByDescending(b => b.Price);
//查詢數(shù)據(jù)2
1、GroupBy也可以
var groups = ctx.Books.GroupBy(b => b.AuthorName)
	.Select(g => new { AuthorName = g.Key, BooksCount = g.Count(), MaxPrice = g.Max(b => b.Price) });
foreach(var g in groups)
{
	Console.WriteLine($"作者名:{g.AuthorName},著作數(shù)量:{g.BooksCount},最貴的價格:{g.MaxPrice}");
}
2、大部分Linq操作都能作用于EF Core。
//修改、刪除
1、要對數(shù)據(jù)進行修改,首先需要把要修改的數(shù)據(jù)查詢出來,然后再對查詢出來的對象進行修改,然后再執(zhí)行SaveChangesAsync()保存修改。
var b = ctx.Books.Single(b=>b.Title== "數(shù)學(xué)之美");
b.AuthorName = "Jun Wu";
await ctx.SaveChangesAsync();
2、刪除也是先把要修改的數(shù)據(jù)查詢出來,然后再調(diào)用DbSet或者DbContext的Remove方法把對象刪除,然后再執(zhí)行SaveChangesAsync()保存修改。
var b = ctx.Books.Single(b => b.Title == "數(shù)學(xué)之美");
ctx.Remove(b);//也可以寫成ctx.Books.Remove(b);
await ctx.SaveChangesAsync();
//批量修改、刪除 性能低:查出來,再一條條Update、Delete,

五、身份驗證(mvc,ef)

ASP.NET Core MVC 登錄驗證
1,創(chuàng)建一個mvc的項目
2,添加包,創(chuàng)建一個實體類,相應(yīng)的上下文類。
3,數(shù)據(jù)庫的遷移,實現(xiàn),program.cs的配置。
4,在HomeController添加[Authorize],
5, 添加一個User控制器,以及視圖Login,添加內(nèi)容_Layout.cshtml

Microsoft.EntityFrameworkCore.Sqlite
Pomelo.EntityFrameworkCore.MySql
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Tools
Add-Migration InitialCreate//實現(xiàn)遷移
Update-database//生成數(shù)據(jù)庫
//User.cs
public class User
{
     public int Id { get; set; }
     public string Account { get; set; }
     public string Password { get; set; }
 }
//MyDbContext.cs
using Microsoft.EntityFrameworkCore;
public class MyDbContext:DbContext
{
    public DbSet<User> Users { get; set; }
    public MyDbContext(DbContextOptions options) : base(options)
    {

    }
}
//program.cs
//builder.Services.AddSqlite<MyDbContext>("Data Source=ContosoPizza.db");//連接Sqlite
builder.Services.AddDbContext<MyDbContext>(options=>options.UseMySql("server=localhost;user=root;password=123456;database=Myhaha",
    new MySqlServerVersion(new Version(5, 6, 0))));
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)//身份驗證
    .AddCookie(options =>
    {
        options.LoginPath = "/User/Login";//初識路徑
    });
app.UseAuthentication();

//UserController.cs
public class UserController : Controller
{
    private readonly MyDbContext _context;
    public UserController(MyDbContext myDbContext)
    {
        _context = myDbContext;
    }
    public IActionResult Index()
    {
        return View();
    }
    public IActionResult Login(string returnUrl)
    {
        ViewData["ReturnUrl"] = returnUrl;
        return View();
    }
    [HttpPost]
    public async Task< IActionResult> Login(UserLoginRequest request)
    {
        if(await _context.Users.AnyAsync(a => a.Account == request.Account && a.Password == request.Password))
            //if (request.Account=="admin"&&request.Password=="admin")
        {
            var claim = new List<Claim>()
            {
                new Claim(ClaimTypes.Name,request.Account),//保存了數(shù)據(jù)。
            };
            var clainmnsIdentity=new ClaimsIdentity(claim, CookieAuthenticationDefaults.AuthenticationScheme);
            await HttpContext.SignInAsync(
                CookieAuthenticationDefaults.AuthenticationScheme,
                new ClaimsPrincipal(clainmnsIdentity),
                new AuthenticationProperties
                {
                    IsPersistent = true,//持久cookie
                });
        }
        else{ return RedirectToAction(nameof(Login));}
       return Redirect(request.ReturnUrl ?? "/");
       //return RedirectToAction(nameof(Index));
    }
    public async Task<IActionResult> Logout()
    {
        await HttpContext.SignOutAsync();
        return RedirectToAction(nameof(Login));
    }
}
public class UserLoginRequest : User
{
    public string ReturnUrl { get; set; }
}

//Login.cshtml
<form asp-action="Login" method="post">
    <input type="hidden" name="returnUrl" value="@ViewBag.ReturnUrl" />
    <input type="text" name="account" value="" />
    <input type="password" name="password" value="" />

    <input type="submit"  value="登錄" />
</form>
//_Layout.cshtml
添加內(nèi)容
<li class="nav-item">
    @User.Identity.Name
</li>
<li class="nav-item">
    <a class="nav-link text-dark" asp-area="" asp-controller="User" asp-action="Logout">退出登錄</a>
</li>

其他

1.數(shù)據(jù)庫表之間的關(guān)系

數(shù)據(jù)庫表之間的關(guān)系:一對一、一對多、多對多

一對多:HasOne(…).WithMany(…);
一對一:HasOne(…).WithOne (…);
多對多:HasMany (…).WithMany(…);

1、IQueryable books = ctx.Books;
books.Where(b => b.Price > 1.1)
2、IEnumerable books = ctx.Books;
books.Where(b => b.Price > 1.1)

  1. 一對多:實體類,一對多:關(guān)系配置
//1、文章實體類Article、評論實體類Comment。一篇文章對應(yīng)多條評論。
public class Article
{
	public long Id { get; set; }
	public string Title { get; set; }
	public string Content { get; set; }
	public List<Comment> Comments { get; set; } 
                       = new List<Comment>(); 
}
public class Comment
{
	public long Id { get; set; }
	public Article Article { get; set; }
	public string Message { get; set; }
}
//一對多:關(guān)系配置
class ArticleConfig : IEntityTypeConfiguration<Article>
{
	public void Configure(EntityTypeBuilder<Article> builder)
	{
		builder.ToTable("T_Articles");
		builder.Property(a => a.Content).IsRequired().IsUnicode();
		builder.Property(a => a.Title).IsRequired().IsUnicode().HasMaxLength(255);
	}
}
class CommentConfig : IEntityTypeConfiguration<Comment>
{
	public void Configure(EntityTypeBuilder<Comment> builder)
	{
		builder.ToTable("T_Comments");
		builder.HasOne<Article>(c=>c.Article).WithMany(a => a.Comments).IsRequired();//HasForeignKey(c=>c.ArticleId)
		builder.Property(c=>c.Message).IsRequired().IsUnicode();
	}
}


//獲取關(guān)系數(shù)據(jù)
Article a = ctx.Articles.Include(a=>a.Comments).Single(a=>a.Id==1);
Console.WriteLine(a.Title);
ctx.Articles.Where(a=>a.Comments.Any(c=>c.Message.Contains("微軟")));
ctx.Comments.Where(c => c.Message.Contains("微軟"))
.Select(c => c.Article).Distinct();
foreach(Comment c in a.Comments)
{
	Console.WriteLine(c.Id+":"+c.Message);
}
//Include定義在Microsoft.EntityFrameworkCore命名空間中
//關(guān)聯(lián)查詢

//CommentConfig:
builder.HasOne<Article>(c=>c.Article).WithMany(a => a.Comments).IsRequired();
//ArticleConfig:
builder.HasMany<Comment>(a => a.Comments).WithOne(c => c.Article).IsRequired();
  1. 一對一關(guān)系
class Order
{
	public long Id { get; set; }
	public string Name { get; set; }
	public string Address { get; set; }
	public Delivery Delivery { get; set;} 
}

class Delivery
{
	public long Id { get; set; }
	public string CompanyName { get; set; }
	public String Number { get; set; }
	public Order Order { get; set; }
	public long OrderId { get; set; }
}

1、builder.HasOne<Delivery>(o => o.Delivery).WithOne(d => d.Order).HasForeignKey<Delivery>(d=>d.OrderId);
2、測試插入和獲取數(shù)據(jù)。
  1. 多對多(老師—學(xué)生。)
class Student
{
	public long Id { get; set; }
	public string Name { get; set; }
	public List<Teacher> Teachers { get; set; } = new List<Teacher>();
}
class Teacher
{
	public long Id { get; set; }
	public string Name { get; set; }
	public List<Student> Students { get; set; } = new List<Student>();
}

builder.HasMany<Teacher>(s => s.Teachers).WithMany(t=>t.Students).UsingEntity(j=>j.ToTable("T_Students_Teachers"));

2.所謂IQueryable

1、IQueryable只是代表一個“可以放到數(shù)據(jù)庫服務(wù)器去執(zhí)行的查詢”,它沒有立即執(zhí)行,只是“可以被執(zhí)行”而已。
2、對于IQueryable接口調(diào)用非終結(jié)方法的時候不會執(zhí)行查詢,而調(diào)用終結(jié)方法的時候則會立即執(zhí)行查詢。
3、終結(jié)方法:遍歷、ToArray()ToList()、Min()、Max()Count()等;
4、非終結(jié)方法:GroupBy()、OrderBy()、Include()、Skip()、Take()等。
5、簡單判斷:一個方法的返回值類型如果是IQueryable類型,那么這個方法一般就是非終結(jié)方法,否則就是終結(jié)方法。

1、IQueryable是一個待查詢的邏輯,因此它是可以被重復(fù)使用的。
2、IQueryable books = ctx.Books.Where(b => b.Price <= 8);
Console.WriteLine(books.Count());
Console.WriteLine(books.Max(b=>b.Price));
var books2 = books.Where(b=>b.PubTime.Year>2000);

1、DataReader:分批從數(shù)據(jù)庫服務(wù)器讀取數(shù)據(jù)。內(nèi)存占用小、 DB連接占用時間長;
2、DataTable:把所有數(shù)據(jù)都一次性從數(shù)據(jù)庫服務(wù)器都加載到客戶端內(nèi)存中。內(nèi)存占用大,節(jié)省DB連接。
驗證IQueryable用什么方式

1、用insert into select多插入一些數(shù)據(jù),然后加上Delay/Sleep的遍歷IQueryable。在遍歷執(zhí)行的過程中,停止SQLServer服務(wù)器。
IQueryable內(nèi)部就是在調(diào)用DataReader。
2、優(yōu)點:節(jié)省客戶端內(nèi)存。
缺點:如果處理的慢,會長時間占用連接。
//如何一次性加載數(shù)據(jù)到內(nèi)存
1、一次性加載數(shù)據(jù)到內(nèi)存:用IQueryable的ToArray()、ToArrayAsync()ToList()、ToListAsync()等方法。
2、等ToArray()執(zhí)行完畢,再斷服務(wù)器試一下。
//何時需要一次性加載
1、場景1:遍歷IQueryable并且進行數(shù)據(jù)處理的過程很耗時。
2、場景2:如果方法需要返回查詢結(jié)果,并且在方法里銷毀DbContext的話,是不能返回IQueryable的。必須一次性加載返回。
3、場景3:多個IQueryable的遍歷嵌套。很多數(shù)據(jù)庫的ADO.NET Core Provider是不支持多個DataReader同時執(zhí)行的。把連接字符串中的MultipleActiveResultSets=true刪掉,其他數(shù)據(jù)庫不支持這個。
//對應(yīng)異步方法
1、SaveChanges()、SaveChangesAsync()
2、異步方法大部分是定義在Microsoft.EntityFrameworkCore這個命名空間下EntityFrameworkQueryableExtensions等類中的擴展方法,記得using。
3AddAsync()、AddRangeAsync()AllAsync()、AnyAsync、AverageAsync、ContainsAsync、CountAsync、FirstAsync、FirstOrDefaultAsync、ForEachAsync、LongCountAsync、MaxAsync、MinAsync、SingleAsync、SingleOrDefaultAsync、SumAsync等

Dapper ORM

https://dapper-tutorial.net/step-by-step-tutorial
https://www.w3cschool.cn/dapperorm/

https://www.jb51.net/article/216497.htm
https://www.codenong.com/cs106392582/
https://www.cnblogs.com/yixuanhan/p/9238781.html
https://blog.csdn.net/dxm809/article/details/112038117

簡單案例

using Dapper;
using MySql.Data.MySqlClient;
using System.Data;
using System.Data.SqlClient;
List<User> user = new List<User>();
string strcon = "Database=traytest;Data Source=localhost;User Id=root;Password=123456;CharSet=utf8;port=3306";
IDbConnection db = new MySqlConnection(strcon);
db.Open();
//queryid(28);

Insert(new User {  name= "2222",age="2222" }); 
//查詢
void query()
{
    user = db.Query<User>("Select * From user").ToList();
    foreach (var item in user)
    {
        Console.WriteLine("name=" + item.name + "~~~age=" + item.age);
    }
}
void queryid(int id)
{
    user = db.Query<User>($"Select * From user where id={id}").ToList();
    foreach (var item in user)
    {
        Console.WriteLine("name=" + item.name + "~~~age=" + item.age);
    }
}
//添加
void Insert(User user)
{
    string insertSqlStr = $"INSERT INTO  user(id,Name,age)VALUES(null,{user.name},{user.age})";
    //db.Execute(insertSqlStr, user); //這種是按實體插入
    db.Execute(insertSqlStr); //這種是按實體插入
}

public class User
{
    public int id { get; set; }
    public string name { get; set; }
    public string age { get; set; }

}


-------------------
        //查詢
        #region Query
        void queryid(int id)
        {
            user = db.Query<User>($"Select * From user where id={id}").ToList();
            foreach (var item in user)
            {
                Console.WriteLine("name=" + item.name + "~~~age=" + item.age);
            }
        }
        #endregion

        #region Update
        //更新
        void Update(User user)
        {
            string sql = "UPDATE user SET name = @name,age=@age WHERE id = (@id)";
            db.Execute(sql, user); //這種是按實體插入
            Console.WriteLine("更新成功");
        }
        //更新多個
        void UpdateNumbs(List<User> users)
        {
            string sql = "UPDATE user SET name = @name,age=@age WHERE id = (@id)";
            db.Execute(sql, users); //這種是按實體插入
            Console.WriteLine("更新成功多個");
        }
        #endregion

        #region Delete
        //刪除
        void Delete(User user)
        {
            string sql = "DELETE FROM user WHERE id = @id";
            db.Execute(sql, user); //這種是按實體刪除
            Console.WriteLine("刪除成功");
        }
        //刪除多個
        void DeleteNumbs(List<User> users)
        {
            string sql = "DELETE FROM user WHERE id = @id";
            db.Execute(sql, users); //這種是按實體刪除多個
            Console.WriteLine("刪除多個");
        }

        #endregion

        #region Add
        //添加
        void Insert(User user)
        {
            //string insertSqlStr = $"INSERT INTO  user(id,name,age)VALUES(null,{user.name},{user.age})";
            string insertSqlStr = $"INSERT INTO  user(id,name,age)VALUES(null,(@name),(@age))";
            //db.Execute(insertSqlStr, user); //這種是按實體插入
            db.Execute(insertSqlStr, user); //這種是按實體插入
            Console.WriteLine("添加成功");
        }
        //添加多個
        void InsertNumbs(List<User> users)
        {
            string insertSqlStr = $"INSERT INTO  user(id,name,age)VALUES(null,(@name),(@age))";
            //db.Execute(insertSqlStr, user); //這種是按實體插入
            db.Execute(insertSqlStr, users); //這種是按實體插入
            Console.WriteLine("添加多個成功");
        }
        #endregion

SqlSugar ORM

官網(wǎng)

簡單案例

//查詢所有
using SqlSugar;
using MySql.Data;
Demo();

static void Demo()
{

    //創(chuàng)建數(shù)據(jù)庫對象
    SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
    {
        ConnectionString = "Database=traytest;Data Source=localhost;User Id=root;Password=123456;CharSet=utf8;port=3306",
        //ConnectionString = "server=localhost;Database=traytest;Uid=root;Pwd=123456; AllowLoadLocalInfile=true",
        DbType = DbType.MySql,
        //DbType = DbType.MySqlConnector,
        IsAutoCloseConnection = true
    });

    //調(diào)試SQL事件,可以刪掉(要放在執(zhí)行方法之前)
    db.Aop.OnLogExecuting = (sql, pars) =>
    {
        Console.WriteLine(sql);//輸出sql,查看執(zhí)行sql
                               //5.0.8.2 獲取無參數(shù)化 SQL 
                               //UtilMethods.GetSqlString(DbType.SqlServer,sql,pars)
    };

    //查詢表的所有
    //var list = db.Queryable<User>().ToList();
    //foreach (var item in list)
    //{
    //    Console.WriteLine("name=" + item.Name + "~~~age=" + item.Age);
    //}

    //插入
    //db.Insertable(new User() { Age="jack", Name = "jack" }).ExecuteCommand();

    //更新
    //db.Updateable(new User() { Id = 30, Age = "jack2", Name = "jack2" }).ExecuteCommand();

    //刪除
    //db.Deleteable<User>().Where(it => it.Id == 30).ExecuteCommand();

}



//實體與數(shù)據(jù)庫結(jié)構(gòu)一樣
public class User
{
    //數(shù)據(jù)是自增需要加上IsIdentity 
    //數(shù)據(jù)庫是主鍵需要加上IsPrimaryKey 
    //注意:要完全和數(shù)據(jù)庫一致2個屬性
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int Id { get; set; }
    public string Age { get; set; }
    public string Name { get; set; }
}

Freesql ORM

官網(wǎng)

簡單案例

IFreeSql fsql = new FreeSql.FreeSqlBuilder()
    .UseConnectionString(FreeSql.DataType.MySql, "Database=traytest;Data Source=localhost;User Id=root;Password=123456;CharSet=utf8;port=3306")
    .UseAutoSyncStructure(true) //自動同步實體結(jié)構(gòu)到數(shù)據(jù)庫,F(xiàn)reeSql不會掃描程序集,只有CRUD時才會生成表。
    .Build(); //請務(wù)必定義成 Singleton 單例模式
List<User> select = fsql.Select<User>().ToList();
foreach (var item in select)
{
    Console.WriteLine(item.Age);
}
//實體與數(shù)據(jù)庫結(jié)構(gòu)一樣
public class User
{
    public int Id { get; set; }
    public string Age { get; set; }
    public string Name { get; set; }
}

ADO.NET(不是orm)

參考鏈接:
官方文檔
易百教程
asp.net連接mysql數(shù)據(jù)庫+mysql公共類
https://blog.csdn.net/qq_23018459/article/details/79446935
對理解有幫助
c#中用來批量更新數(shù)據(jù)庫SqlCommandBuilder文章來源地址http://www.zghlxwxcb.cn/news/detail-444179.html

  • 由于Ado直接操作數(shù)據(jù)庫,性能開銷最小;而ORM架構(gòu)大多使用反射來獲取對象屬性,然后映射成數(shù)據(jù)字段,或者反過來把字段映射成屬性,反射有性能上的開銷。
  • 五大對象:
    Connection(連接對象)
    Command(命令對象)
    DataReader(只讀,數(shù)據(jù)庫)
    DataAdapter(數(shù)據(jù)適配器)
    DataSet(數(shù)據(jù)集對象)

到了這里,關(guān)于.NET-4.ORM 常見框架EFcorn、Dapper、SqlSugar、FreeSql 和ADO.NET的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • SqlSugar ORM 入門(簡介和增刪查改)

    SqlSugar ORM 入門(簡介和增刪查改)

    背景 SqlSugar ORM是一個國產(chǎn)的,提供對象/關(guān)系映射(ORM)的庫。 (ORM 是 Object Relational Mapping 的縮寫,譯為“對象關(guān)系映射”。 它解決了對象和關(guān)系型數(shù)據(jù)庫之間的數(shù)據(jù)交互問題。? ? ? ? ? ? ? ? ? ? ? ? 使用面向?qū)ο缶幊虝r,數(shù)據(jù)很多時候都存儲在對象里面,具體來說是

    2024年02月03日
    瀏覽(14)
  • ORM核心功能之導(dǎo)航屬性- EFCore和 SqlSugar

    導(dǎo)航屬性是作為.NET ORM核心功能中的核心,在SqlSugar沒有支持導(dǎo)航屬性前,都說只是一個高級DbHelper, 經(jīng)過3年的SqlSugar重構(gòu)已經(jīng)擁有了一套 非常成熟的導(dǎo)航屬性體系,本文不是重點講SqlSugar而是重點講導(dǎo)航屬性的作用,讓更多寫Sql人還未使用ORM的人了解到ORM的作用。 ? 用戶根據(jù)

    2024年02月07日
    瀏覽(17)
  • 執(zhí)行SQL語句&存儲過程的真正【神器】,不用ORM的全選它,比dapper好

    執(zhí)行SQL語句&存儲過程的真正【神器】,不用ORM的全選它,比dapper好

    支持.Net Core(2.0及以上)與.Net Framework(4.0及以上)(注意:升級了,可以覆蓋到早期的.Net Framework4.0了,而且修復(fù)了數(shù)據(jù)庫字段為Null時報錯的問題,無敵了?。? 此工具在IDataAccess接口中提供。?已被.Net圈內(nèi)多家大廠采用! IDataAccess所在的命名空間是:DeveloperSharp.Framework.QueryEngine(

    2024年02月08日
    瀏覽(16)
  • c# 實現(xiàn)sql查詢DataTable數(shù)據(jù)集 對接SqlSugar ORM

    有時候?qū)τ谝呀?jīng)查詢到的數(shù)據(jù)集,想要進行二次篩選或者查詢,還得再查一遍數(shù)據(jù)庫 或者其他的一些邏輯處理不太方便,就想著為什么不能直接使用sql來查詢DataTable呢? 搜索全網(wǎng)沒找到可用方案,所以自己實現(xiàn)了一個。 主要實現(xiàn)思路是使用 SQLite In-Memory Database 內(nèi)存數(shù)據(jù)庫,

    2024年02月12日
    瀏覽(23)
  • .Net6下使用Ado.Net

    .Net6下使用Ado.Net

    Ado.Net,是微軟提供的在.Net平臺下操作數(shù)據(jù)庫(本文實例記錄MySQL、SQLSever數(shù)據(jù)的基本操作)、XML文件和應(yīng)用程序數(shù)據(jù)的一個工具。是應(yīng)用程序和數(shù)據(jù)庫之間的數(shù)據(jù)橋梁。它擁有一組豐富的類、方法和接口,有效地處理數(shù)據(jù)庫中的數(shù)據(jù)。(上層的ORM框架《EFCore、Dapper等》都是對它

    2024年02月05日
    瀏覽(25)
  • ADO.NET 概述

    ADO.NET 是.NET Framework中提供了專門用來處理數(shù)據(jù)的技術(shù)。通過該技術(shù),開發(fā)人員可以訪問SQL Server、 ODBC、 Oracle、 OLE DB、XML 等數(shù)據(jù)源,并檢索、操作和更新這些數(shù)據(jù)源中的數(shù)據(jù)。 ADO.NET 組成結(jié)構(gòu): ADO.NET 是.NET Framework 中的一部分, 提供對 Microsoft SQL Server. ODBC、 Oracle等數(shù)據(jù)源,以及通

    2024年02月05日
    瀏覽(22)
  • .NET Dapper mysql 批量新增修改

    ? ?

    2024年02月11日
    瀏覽(16)
  • C# .NET ADO.NET介紹和如何使用

    C# .NET ADO.NET介紹和如何使用

    .NET Framework 4.7.2 Visual Studio 2022 Sql server 2008 新建項目 我們看一下visual studio 里面ADO.NET文件 ADO.NET是實體數(shù)據(jù)模型,是ORM對象文件。ORM,即Object-Relational Mapping(對象關(guān)系映射)。 ORM實際上是對業(yè)務(wù)的簡化。就想面向過程到面向?qū)ο蟮霓D(zhuǎn)變一樣。 面向過程和面向?qū)ο?面向過程:程序

    2024年02月09日
    瀏覽(29)
  • Ado.Net 數(shù)據(jù)庫訪問技術(shù)(.Net 6版本)

    Ado.Net 數(shù)據(jù)庫訪問技術(shù)(.Net 6版本)

    ADO.NET的名稱起源于ADO(ActiveX Data Objects),是一個COM組件庫,用于在以往的Microsoft技術(shù)中訪問數(shù)據(jù)。之所以使用ADO.NET名稱,是因為Microsoft希望表明,這是在NET編程環(huán)境中優(yōu)先使用的數(shù)據(jù)訪問接口。 ADO.NET可讓開發(fā)人員以一致的方式存取資料來源(例如 SQL Server 與 XML),以及透

    2024年02月07日
    瀏覽(22)
  • ADO.Net前端頁面調(diào)用后臺方法使用

    1、前臺頁面定義GetSource方法,傳入列表顯示字段; 2、后臺頁面定義Public公共類型的方法GetSource; 3、后臺可以根據(jù)字段值判斷列中需要顯示的圖標、數(shù)值;

    2024年02月01日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包