本文章是我听B站杨中科的所做的笔记

杨中科B站视频链接:.NET 6教程,.Net Core 2022视频教程,杨中科主讲_哔哩哔哩_bilibili

什么时ORM

1、说明:本课程需要你有数据库、SQL等基础知识

2、ORM:Object Relational Mapping。让开发者用对象操作的形式操作关系数据库 比如插入:

User user = new User(){Name="admin",Password="123"};
orm.Save(user);

比如查询:

Book b = orm.Books.Single(b=>b.Id==3||b.Name.Contains(".NET"));
string bookName = b.Name;
string aName = a.Author.Name;

3、有哪些ORM:EF Core、Dapper、SqlSugar、FreeSql等

EF Core与其他ORM比较

1、Entity Framework Core(EF Core)是微软官方ORM框架。优点:功能强大、官方支持、生产效率高、力求屏蔽数据库差异;缺点:复杂、上手门槛高、不熟悉EFCore的话可能会进坑。

2、Dapper。优点:简单、N分钟即可上手,行为可预期性强;缺点:生产效率低,需要处理底层数据库差异

3、EF Core是模型驱动的开发思想,Dapper是数据库驱动的开发思想的。没有优劣,只有比较。

4、性能:Dapper不等于性能高;EF Core不等于性能差。

5、EF Core是官方推荐、推进的框架,尽量屏蔽底层数据库差异,.NET开发者必须熟悉,根据的项目情况再决定用哪个。

选择

1、建议:对于后台系统、信息系统等和数据库相关开发工作量大的系统,且团队比较稳定,用EF Core;对于互联网系统等数据库相关工作量不大的系统,或者团队不稳定,用Dapper

2、在项目中可以混用,只要注意EF Core的缓存、Tracking等问题即可

EF Core与EF比较

1、EF有DB First、Model First、Code First。EF Core不支持模型优先,推荐使用代码优先,遗留系统可以使用ScafffoldDbContext来生成代码实现类似DBFirst的效果,但是推荐用Code First

2、EF会对实体上的标注做校验,EF Core追求轻量化,不校验。

3、熟悉EF的话,掌握EFCore会很容易,很多用法都移植过来了,EF Core又增加了很多新东西 4、EF中一些类的命名空间以及一些方法的名字再EF Core中稍有不同。

5、EF不再做新特性增加

搭建EF Core环境

用什么数据库

1、EF Core是对于底层ADO.NET Core的封装,因此ADO.NET Core支持的数据库不一定被EF Core支持

2、EF Core支持所有主流的数据库,包括MS SQL Server、Oracle、MySql、PostgreSql、Sqlite等。可以自己实现Provider支持其他数据库。国产数据库支持问题

3、对于SQLServer支持最完美,MySql、PostgreSQL也不错(有能解决的小坑)。这三者是.NET圈中用的最多的三个。EF Core能尽量屏蔽底层数据库差异

开发环境搭建

1、经典步骤:建实体类;建DbCotext;生成数据库;编写调用EF Core的业务代码

2、Boos.cs

public class Book{public long Id { get; set; }//主键public string Title { get; set; }//标题public DateTime PubTime { get; set; }//发布日期public double Price { get; set; }//单价}

3、Install-Package Microsoft.EntityFrameworkCore.SqlServer

4、创建实现了IEntityTypeConfiguration接口的实体配置类,配置实体类和数据库的对应关系

class BookEntityConfig : IEntityTypeConfiguration<Book>
{public void Configure(EntityTypeBuilder<Book> builder){builder.ToTable("T_Books");}
}

5、创建继承自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);}
}

6、migration数据库迁移 面向对象的开发中,数据库不是程序员手动创建的,而是由Migration工具生成的。关系数据库只是存放模型数据的一个媒介而已,理想状态下,程序员不用关心数据库的操作。根据对象的定义变化,自动更新数据库的表以及表结构的操作,叫做Migration(迁移)。迁移可以分为多步(项目进化),也可以回滚。

7、为了使用生成数据库的工具,Nuget安装:Microsoft.EntityFrameworkCore.Tool,否则执行Add-Migration等命令会报错

8、再”程序包管理控制台“中执行如下命令Add-Migration InitialCreate,会自动再项目的Migration文件夹中生成操作数据库的C#操作。代码需要执行后才会应用对数据库的操作。”程序包管理器控制台“中执行Update-database。查看一下数据库,表建好了

9、修改表结构

1)项目开发中,根据需要,可能会在已有实体中修改、新增、删除表、列等

2)想要限制Title的最大长度为50,Title字段设置为”不可为空“,并且想增加一个不可为空且最大长度为20的AuthorName(作者名字)属性,首先子啊Book实体类中增加一个AuthorName属性

3)修改BookEntityConfig

builder.ToTable("T_Books");
builder.Property(e => e.Title).HasMaxLength(50).IsRequired();
builder.Property(e => e.AuthorName).HasMaxLength(20).IsRequired();

4)执行Add-Migration AddAuthorName_ModifyTitle。取名字由意义

5)执行Update-Database

EF Core增删改查

插入输入

1、只要操作Books属性,就可以向数据库中增加数据,但是通过C#代码修改Books中的数据只是修改内存中的数据。对Books做修改后,需要调用DbContext的异步方法SaveChange(),但是用EF Core都推荐用异步方法

2、EF Core默认会跟踪(Track)实体类对象以及DbSet的改变

查询数据

1、DbSet实现了IEnumberable<T>接口,因此可以对DbSet实施Linq操作来进行数据查询。EF Core会把Linq操作转换为SQL语句。面向对象,而不是面向数据库(SQL)

ctx.Books.Where(b => b.Price > 80)
Book b1 = ctx.Books.Single(b => b.Title== "零基础趣学C语言");
Book b2 = ctx.Books.FirstOrDefault(b=>b.Id==9);

可以使用OrderBy操作进行数据的排序

IEnumerable<Book> books = ctx.Books.OrderByDescending(b => b.Price);

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},著作数量:{g.BooksCount},最贵的价格:{g.MaxPrice}");
}

大部分Linq操作都能作用与EF Core

修改、删除

1、要对数据进行修改,首先需要把要修改的数据查询出来,然后再对查询出来的对象进行修改,然后再执行SaveChangesAsync()保存修改

var b = ctx.Books.Single(b=>b.Title== "数学之美");
b.AuthorName = "Jun Wu";
await ctx.SaveChangesAsync();

2、删除也是先把要删除的数据查询出来,然后再调用DbSet或者DbContext的Remove方法把对象删除然后再执行SaveChangeAsync()保存修改。

var b = ctx.Books.Single(b => b.Title == "数学之美");
ctx.Remove(b);//也可以写成ctx.Books.Remove(b);
await ctx.SaveChangesAsync();

批量修改、删除

1、目前批量修改、删除多条数据的方法:局限性、性能低:查出来,再一条条Update、Delete,而不能执行Update ...where;delete ... where;

2、官方目前还没有支持高效的批量Update、Delete,有在后续版本中共增加,但是目前只是前期意见征询阶段

3、有一个开源的高效批量修改、删除的开源项目。Zack.EFCore.Batch GitHub - yangzhongke/Zack.EFCore.Batch: Deleting or Updating multiple records from a LINQ Query in a SQL statement without loading entities

EF Core实体配置

约定配置

主要规则:

1、表明采用DbContext中的对应的DbSet的属性名

2、数据表列的名字采用实体类属性名字,列的数据类型采用和实体类属性类型最兼容的类型

3、数据表列的可空性取决于对应实体类属性的可空性

4、名字为Id的属性为主键,如果主键为short,int或者long类型,则默认采用自增字段,如果主键为Guid类型,则默认采用默认的Guid生成机制生成主键值

两种配置方式

Data Annotation

1、把配置以特性(Annotation)的形式标注再实体类中。

[Table("T_Books")]
public class Book
{
}

优点:简单;缺点:耦合

2、Fluent API: builder.ToTable("T_Books"); 把配置写到单独的配置类中。缺点:复杂;优点:解耦

3、大部分功能重叠。可以混用,但是不建议混用

Fluent API

1、视图与实体类映射:modelBuilder.Entity<Blog>().ToView("blogsView");

2、排除属性映射:modelBuilder.Entity<Blog>().Property.Ignore(b=>b.Name2);

3、配置列名:modelBuilder.Entity<Blog>().Property(b=>b.BlogId).HasColumnName("blog_id") 4、配置列数据类型:builder.Property(e=>e.Title).HasColumnType("varchar(200)")

5、配置主键:默认把名字为Id或者“实体类型+Id”的属性作为主键,可以用HasKey()来配置其他属性作为主键。modelBuilder.Entity<Student>().HasKey(c=>c.Number);支持复合主键,但是不建议使用

6、生成列的值:modelBuilder.Entity<Student().Property(b=>b.Number).ValueGenerateOnAdd();

7、可以用HasDefaultValue()为属性设定默认值modelBuilder.Entity<Student>().Property(b=>b.Age).HasDefaultValue(6);

8、

a)索引:modelBuilder.Entity<Blog>().HasIndex(b=>b.Url);

b)复合索引:modelBuilder.Entity<Person>().HasIndex(p=>new{p.FirstName,p.LastName});

c)唯一索引:IsUnique(); d)聚集索引:InClustered();

9、使用EF Core高级特性的时候谨慎,尽量不要和业务逻辑混合在一起,以免“不能自拔”。比如Ignore、Shadow、Table Splitting等。。。。

10、Fluent API 众多方法 Fluent API中很多方法都有多个重载。比如HasIndex、Property()。把Number属性定义为索引,下面两种方法都可以:

builder.HasIndex("Number");
builder.HasIndex(b=>b.Number);

推荐使用HasIndex(b=>b.Number).Property(b=>b.Number)这样的写法,因为这样利用的是C#的强类型检查机制

11、选择

a)Data Annotation、Fluent API大部分功能重叠。可以混用,但是不建议混用

b)有人建议混用,即用了Data Annotation的简单,又用到Fluent API的强大,而且实体类标注的【MaxLength(50)】、【Required】等标注可以被ASP.NET Core中的验证框架等复用。建议混用

c)很多人都倾向只使用Fluent API。主要讲解Fluent API为主(尽量用约定),如果项目强制用Data Annotation请翻文档,知识都是通用的

主键不是小事

自增主键

1、EF Core支持多种主键生成策略:自增增长;Guid;Hi/Lo算法等

2、自动增长。优点:简单;缺点:数据库迁移以及分布式系统中比较麻烦;并发性能差。long、int等类型主键,默认是自增。因为是数据库生成的值,所以SaveChanges后会自动把主键的值更新到Id属性。试验一下。场景:插入帖子后,自动重定向帖子地址。

3、自增字段的代码中不能为Id赋值,必须保持默认值0,否则运行的时候就会报错

Guid主键

1、Guid算法(或UUID算法)生成一个全局唯一的Id。适合于分布式系统,在进行多数据库数据合并的时候很简单。优点:简单,高并发,全局唯一;缺点:磁盘空间占用大

2、Guid值不连续。使用Guid类型做主键的时候,不能把主键设置为聚集索引。因为聚集索引是按照顺序保存主键的,因此用Guid做主键性能差。比如MySql的InnoDB引擎中主键是强制使用聚集索引的。有的数据支持部分的连续Guid,比如SQLServer中的NewSequentialId(),但也不能解决问题,在SQLServer等中,不要把Guid主键设置为聚集索引;在MySql中,插入频繁的表不要用Guid做主键

3、Guid既可以让EF Core给赋值,也可以手动赋值(推荐)

其他方案

1、混合自增和Guid(非复合主键)。用自增列做物理的主键,而用Guid列做逻辑上的主键。把自增列设置为表的主键,而在业务上查询数据的时候把Guid当主键用。在和其他表关联以及和外部系统通讯的时候(比如前端显示数据的标识的时候)都是使用Guid列。不仅保证了性能,而且利用了Guid的优点,而且减轻了主键自增性导致主键值可被预测带来的安全性问题

2、Hi/Lo算法:EF Core支持Hi/Lo算法来优化自增列。子增值有两部分组成:高位(Hi)和低位(Lo),高位由数据库生成,两个高位之间间隔若干个值,由程序在本地生成低位,低位的值在本地自增生成。不同进程或者集群中不同服务器获取的Hi值不会重复,而本地进程计算的Lo则可以保证可以在本地高效率的生成主键值。但是HiLo算法不是EF Core的标准

Migrations

深入研究Mirations

1、使用迁移脚本,可以对当前连接的数据库执行编号更高的迁移,这个操作叫做“向上迁移”(Up),也可以执行把数据回退到旧的迁移,这个操作叫做“向下迁移”(Down)

2、除非由特殊情况,否则不要删除Migrations文件夹下的代码

3、进一步分析Migrations下的代码。分析Up、Down等方法。查看Migration编号

4、查看数据库的_EFMigrationsHistory表:记录当前数据库曾经应用过的迁移脚本,按顺序排列

Migrations其他命令

1、Update-Database XXX 把数据库回滚S到XXX的状态,迁移脚本不动。

2、Remove-Migration 删除最后一次的迁移脚本

3、Script-Migration 生成迁移SQL代码,有了Update-Database为什么还要生成SQL脚本。可以生成版本D到版本F的SQL脚本:Script-Migration D F;生成版本D到最新版本的SQL脚本:Script-Migration D

反向工程

1、根据数据库表来反向生成实体类

2、Scaffold-DbContext 'Server=.;Dabataba=demo;Trusted_Connection=True;MultipleActiveResultSets=true' Microsoft.EntityFrameworkCore.SqlServer

注意:

1、生成的实体类可能不能满足项目的需求,可能需要手工修改或者增加配置

2、再次运行反向工程工具,对文件所做的任何更改都将丢失

3、不建议把反向工具当成了日常开发工具使用,不建议DBFirst

EF Core底层如何操作数据库

传统的模式:

使用ORM框架模式:

EF Core模式。EF Core是把C#代码转换为SQL语句的框架:

查看生成的SQL语句

1、SQL Server Profiler查看SQLServer数据库当前执行的SQL语句

2、var book = ctx.Books.Where(b=>b.Price>10||b.Title.Contains("张"))

有哪些是EF Core是做不到的

why:

1、C#千变万化;SQL功能简单。存在合法的C#语句无法被翻译为SQL语句的情况

var books = ctx.Books.Where(b => IsOK(b.Title));
private static bool IsOK(string s)
{return s.Contains("张");
}
var books = ctx.Books.Where(b =>b.Title.PadLeft(5)=="hello");

不同数据的不同:

通过代码查看EF Core生成的SQL

标准日志:

//方法1
public static readonly ILoggerFactory MyLoggerFactory= LoggerFactory.Create(builder => { builder.AddConsole(); });
​
optionsBuilder.UseLoggerFactory(MyLoggerFactory);
​
//方法2 可以自己写代码过滤一些不需要的信息
optionsBuilder.LogTo(Console.WriteLine);

方法3:

1、上面两种方法无法直接得到一个操作的SQL语句,而且操作很多的情况下,容易混乱

2、EF Core的Where方法返回的是IQueryable类型,DbSet也实现了IQueryable接口。IQueryable有扩展方法ToQueryString()可以获得SQL

3、不需要真的执行查询才获取SQL语句;只能获取查询操作的

总结:写测试行代码,用简单日志;正式需要记录SQL给审核人员或者排查故障,用标准日志;开发阶段,从繁杂的查询操作中立即看到SQL,用ToQueryString()。

同样的Linq被翻译为不同的SQL语句

不同数据库方言不同

SqlServer:select top(3) * from t

MySql:select * from t limit 3

Oracle:select * from t where RowNum<=3 C#代码:

var books = ctx.Books.Where(b=>b.PubTime.Year>2010).Take(3);
foreach(var b in books)
{Console.WriteLine(b.Title);
}

同样的C#语句在不同数据库中被EF Core翻译成不同的SQL语句

因此迁移脚本不能跨数据库。通过给Add-Migration命令添加“-OutputDir”参数的形式来在同一个项目中为不同数据库生成不同的迁移脚本

MySQL项目中测试

1、EF Provider的选择:

2、Install-Package Pomelo.EntityFrameworkCore.MySql

3、optionBuilder.UseMySql("server=localhost;user=root;password=root;database=ef",new MySqlServerVersion(new Version(5,6,0)))

PostgreSQL项目中测试 。开源项目的主要贡献者是微软EF团队的主程序员,因此这个项目的可靠性还是比较高的。

1、Install-Package Npgsql.EntityFrameworkCore.PostgreSQL 2、optionBuilder.UseNpgsql("Host=127.0.0.1;Database=ef;Username=postgres;Password=123456")

EF Core一对多关系配置

什么是实体间关系

1、所谓“关系数据库”

2、复习:数据库表之间的关系:一对一、一对多、多对多

3、EF Core不仅支持单实体操作,更支持多实体的关系操作

4、三部曲:实体类中关系属性;FluentAPI关系配置;使用关系操作

一对多:实体类

1、文章实体类Article、评论实体类Comment。一篇文章对应多条评论

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; }
}

一对多:关系配置

EF Core中实体之间关系的配置的套路:HasXXX(...).WithXXX(...);有XXX、反之带有XXX。XXX可选值One、Many 一对多:HasOne(...).WithMany(...); 一对一:HasOne(...).WithOne(...); 多对多:HasMany(...).WithMany(...);

一对多:关系配置

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();builder.Property(c=>c.Message).IsRequired().IsUnicode();}
}

一对多:实验

1、迁移生成数据库表

2、编写代码测试数据插入

3、不需要显式为Comment对象的Article属性赋值(当前赋值也不会出错),也不需要显式地把新创建的Comment类型的对象添加到DbContext。EF Core会“'顺竿爬'

Article a1 = new Article();
a1.Title = "微软发布.NET 6大版本的首个预览";
a1.Content = "微xxxx";
Comment c1 = new Comment() { Message="支持"};
Comment c2 = new Comment() { Message = "微软太牛了" };
Comment c3 = new Comment() { Message = "火钳刘明" };
a1.Comments.Add(c1);
a1.Comments.Add(c2);
a1.Comments.Add(c3);
using (TestDbContext ctx = new TestDbContext())
{ctx.Articles.Add(a1);await ctx.SaveChangesAsync();
}

一对多关系数据的获取

Article a = ctx.Articles.Include(a=>a.Comments).Single(a=>a.Id==1);
Console.WriteLine(a.Title);
foreach(Comment c in a.Comments)
{Console.WriteLine(c.Id+":"+c.Message);
}

Include定义在Microsoft.EntityFrameworkCore命名空间中。查看一下生成的SQL语句

如果没有Include,就没有关联,就查不到数据了

EF Core额外的外键字段

为什么需要外键属性?

1、EF Core会在数据库表中建外键列

2、如果需要获取外键列的值,就需要做关联查询,效率低

3、需要一种不需要Join直接获取外键列的值的方式

设置外键属性:

1、在实体类中显式声明一个外键属性

2、关系配置中通过HasForeignKey(c=>c.ArticleId)指定这个属性为外键

3、除非必要,否则不用声明,因为会引入重复

EF Core单项导航属性

配置方法:不设置反向的属性,然后配置的时候WithMany()不设置参数即可

单向属性如何反向获取数据:再查询一下即可:ctx.Leaves.Where(l=>l.Requester==u)

选择:对于主从结构的”一对多“表关系,一般是声明双向导航属性。而对于其他的”一对多“表关系,则用单项导航属性,否则可以自由决定是否用双向导航属性

关系配置在任何一方都可以

反着配置也可以:

//CommentConfig:
builder.HasOne<Article>(c=>c.Article).WithMany(a => a.Comments).IsRequired();
//ArticleConfig:
builder.HasMany<Comment>(a => a.Comments).WithOne(c => c.Article).IsRequired();

推荐策略:考虑到有单项导航属性的可能,我们一般用HasOne().WithMany()

自引用的组织结构树

代码:

class OrgUnit
{public long Id { get; set; }public string Name { get; set; }public OrgUnit Parent { get; set; }public List<OrgUnit> Children { get; set; } = new List<OrgUnit>();
}

配置:

builder.ToTable("T_OrgUnits");
builder.Property(o => o.Name).IsRequired().IsUnicode().HasMaxLength(100);
builder.HasOne<OrgUnit>(u => u.Parent).WithMany(p => p.Children);

测试:

1、测试数据插入

2、测试递归缩进打印:

static async Task Main(string[] args)
{using (TestDbContext ctx = new TestDbContext()){OrgUnit ouRoot = ctx.OrgUnits.Single(o=>o.Parent==null);Console.WriteLine(ouRoot.Name);PrintChildren(0, ctx, ouRoot);}
}
​
static void PrintChildren(int indentLevel, TestDbContext ctx,OrgUnit parent)
{//获取以parent为父节点的组织单元var children = ctx.OrgUnits.Include(o => o.Children).Where(o=>o.Parent==parent);indentLevel++;//缩进级别foreach (var ou in children){Console.Write(new string('+',indentLevel));//输出缩进Console.WriteLine(ou.Name);PrintChildren(indentLevel, ctx, ou);}
}

EF Core 一对一

在“一对多”的关系中,很显然是需要在“多”端有一个指向“一”端的列,因此除非我们需要显式的声明一个外键属性,否则EF Core会自动在“多”端的表中生成一个指向“一”端的外键列,不需要我们显式的声明一个外键属性。对于一对一关系,由于双方是“平等”的关系,外键列可以建在任意一方,因此必须显式的在其中一个实体类中声明一个外键属性。代码:

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; }
}

配置:

builder.HasOne<Delivery>(o => o.Delivery).WithOne(d => d.Order).HasForeignKey<Delivery>(d=>d.OrderId);

EF Core 多对多关系

1、多对多:老师---学生

2、EF Core5.0开始,才正式支持多对多

3、需要中间表,举例数据

代码:

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>();
}

多对多的关系配置可以放到任何一方的配置类中,我这里把关系配置代码放到了Student类的配置中。配置:

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

测试代码:

1、测试数据插入

2、查询一下所有老师,并且列出它们的学生

EF Core的学习之路01相关推荐

  1. C语言-学习之路-01

    C语言学习之路-01 目录 关键字 数据类型 常量 变量 声明和定义 进制 sizeof关键字 整型:int short.int.long.long long 字符型:char ASCII对照表 转义 ...

  2. Linux学习之路01

    决心开始学习自学Linux,以前混迹贴吧,现在觉得自己开始写一下博客,记录一下自己的学习之路,同时也是希望自己算是自己自学动手练习的记录吧. -- 题序 登录SSH服务 新建一个hello.c文件 # ...

  3. python 零基础学习之路-01 计算机硬件

    一套完整的计算机系统分为:计算机硬件,操作系统,应用软件,如下图.因而我们的python编程之路分为计算机硬件基础,操作系统基础,和python编程三部分,而我们便是最先从计算机硬件开始学习的. 一 ...

  4. 我的HTML学习之路01

    写在前面: 此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) HTML学习 HTML HTML基础 实例 HTML标题 H ...

  5. Java学习之路01——2021年职业规划

    目录 前言 1.职业规划 2.2020年12月--->2021年12月学习计划 2.1.java技术栈 2.2.学习要求 2.3.学习时间 2.4.学习方式 2.5.最终达到的水平 总结 前言 ...

  6. KDL学习之路01:KDL(Kinematics and Dynamics Library)入门学习

    前言:搞工业机器人研究的,很少有不知道KDL的吧,机器人的正.逆运动学求解是一个非常重要的内容. KDL源码编译安装 首先在github上下载KDL的最新源码,接着通过手动编译安装. cd oroco ...

  7. Axure学习之路01——元件介绍

    本系列博客的目的是记录Auxure软件使用的一些要点. 学习课程来自:Axure 9从入门到精通. 目录 一些设计资源 基本元件 图片 占位符 图像热区 动态面板 内联框架 中继器 表单元件 文本框 ...

  8. libGDX学习之路01(续):把libGDX项目部署到iOS

    前言 libGDX是一个非常强大的框架,我在写下libGDX入门那篇文章的时候,没能成功解决把libGDX项目部署到iOS设备上并运行,在我查了很多资料和反复实验中,我总结了一些经验,希望能帮到大家. ...

  9. 【三维重建学习之路01】点云ply文件的读写、修改

    文章目录 1.前言 2.PLY文件格式 3.读文件 变量.库 查看头文件.vertex信息 数据类型 读文件函数 按行阅读检查 4.写文件 参考: 1.前言 关于使用python读写ply的比较清楚的 ...

最新文章

  1. squid 优化指南
  2. c++ 优先队列_什么是队列?(Python队列)
  3. dw1000 配置无法通过
  4. grep 匹配制表符 和 换行符
  5. python做的大型游戏_Python实现数据量较大的生命游戏
  6. php远程读取几行文件,PHP读取远程文件的三种方法
  7. Rust+Yew之hello world
  8. No module named 'django.core.urlresolvers
  9. 机器学习实战(1)-文本分类
  10. Word里仅修改字母和数字的字体,不改变标点符号字体
  11. 算法入门:日期计算(附蓝桥杯)
  12. welearn综合教程网课答案
  13. matlab 三角函数 和差化积,三角函数中的和差化积公式编辑方法
  14. Android 模拟器实现打电话
  15. Linux下的USB驱动
  16. linux下 etho网卡设置
  17. 永信至诚:乌镇世界互联网大会闭幕 网络安全人的使命刚刚启航
  18. mysql 等距_Python气象绘图教程(十一)
  19. 山东理工大学计算机考研复试分数线,山东理工大学2020考研分数线_山东理工大学2020考研复试分数线 - 考研营...
  20. 比亚迪和特斯拉销量爬虫

热门文章

  1. 一条sql是如何执行的
  2. 编译原理第三版课后答案
  3. QA与QC质量管理对比
  4. 精准营销!用机器学习完成客户分群!
  5. linux设置网卡接受组播,linux下双网卡接收组播需要修改的参数
  6. 干货必看|Spring Boot整合MyBatis框架详解
  7. 初识 jquery.simulate.js 模拟键盘事件
  8. 网络编程Socket之wireshark使用
  9. 2014年C++大会的嘉宾演讲稿开放下载
  10. sanic入门(一)