简书链接:dotnetefcore脚手架快速搭建办法
文章字数:828,阅读全文大约需要3分钟
刚开始学ef框架,从网上模仿写的,代码,结果后面执行出了问题。。
发现有一个更快的方法
先配置好环境
https://docs.microsoft.com/en-us/ef/core/cli/dotnet

1
2
3
4
5

dotnet tool install --global dotnet-ef
dotnet tool update --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet ef

进入项目
PS C:\Users\惠普\source\repos\CoreWebApi_>
网上的教程输入dotnet ef提示
无法执行,因为找不到指定的命令或文件。
可能的原因包括:
*内置的 dotnet 命令拼写错误。
原因就是上面dotnet tool install --global dotnet-ef这个东西没装
dotnet ef dbcontext scaffold Server=localhost;Database=efcorelearn;User=root;Password=password; Pomelo.EntityFrameworkCore.MySql -o Models

上面的代码就是连接数据库然后进行分析产生对应的代码放到Models文件夹里面
DigitalTwinContext.cs的命名是根据数据库命名自动识别生成的。
相当规范,于是我删除了我手动写的 一套

image.png

image.png

主要看看怎么 context写的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace CoreWebApi_.Models
{
public partial class DigitalTwinContext : DbContext
{
public DigitalTwinContext()
{
}

public DigitalTwinContext(DbContextOptions<DigitalTwinContext> options)
: base(options)
{
}

public virtual DbSet<Node> Nodes { get; set; } = null!;
public virtual DbSet<NodesTemp> NodesTemps { get; set; } = null!;
public virtual DbSet<View> Views { get; set; } = null!;

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
optionsBuilder.UseSqlServer("Data Source=192.168.1.124;Initial Catalog=DigitalTwin;User ID=SA;Password=12345678;Connect Timeout=15");
}
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Node>(entity =>
{
entity.HasNoKey();

entity.Property(e => e.Descript)
.HasMaxLength(500)
.IsUnicode(false);

entity.Property(e => e.Flag)
.HasColumnName("flag")
.HasDefaultValueSql("((0))");

entity.Property(e => e.Id)
.ValueGeneratedOnAdd()
.HasColumnName("id");

entity.Property(e => e.ItemDescript)
.HasMaxLength(50)
.IsUnicode(false)
.HasColumnName("itemDescript");

entity.Property(e => e.ItemName)
.HasMaxLength(50)
.IsUnicode(false)
.HasColumnName("itemName");

entity.Property(e => e.Name)
.HasMaxLength(50)
.IsUnicode(false);

entity.Property(e => e.Parent)
.HasColumnName("parent")
.HasDefaultValueSql("((0))");

entity.Property(e => e.ParentId).HasColumnName("parentId");

entity.Property(e => e.Tag)
.HasMaxLength(50)
.IsUnicode(false)
.HasColumnName("tag");
});

modelBuilder.Entity<NodesTemp>(entity =>
{
entity.HasNoKey();

entity.ToTable("NodesTemp");

entity.Property(e => e.Descript)
.HasMaxLength(500)
.IsUnicode(false);

entity.Property(e => e.Id)
.ValueGeneratedOnAdd()
.HasColumnName("id");

entity.Property(e => e.ItemDescript)
.HasMaxLength(50)
.IsUnicode(false)
.HasColumnName("itemDescript");

entity.Property(e => e.ItemName)
.HasMaxLength(50)
.IsUnicode(false)
.HasColumnName("itemName");

entity.Property(e => e.Name)
.HasMaxLength(50)
.IsUnicode(false);

entity.Property(e => e.ParentId).HasColumnName("parentId");

entity.Property(e => e.Tag)
.HasMaxLength(50)
.IsUnicode(false)
.HasColumnName("tag");
});

modelBuilder.Entity<View>(entity =>
{
entity.HasNoKey();

entity.Property(e => e.Data)
.HasMaxLength(50)
.IsUnicode(false)
.HasColumnName("data");

entity.Property(e => e.Height).HasColumnName("height");

entity.Property(e => e.Id)
.ValueGeneratedOnAdd()
.HasColumnName("id");

entity.Property(e => e.Is3d).HasColumnName("is3d");

entity.Property(e => e.Parent).HasColumnName("parent");

entity.Property(e => e.ParentName)
.HasMaxLength(50)
.IsUnicode(false)
.HasColumnName("parentName");

entity.Property(e => e.Scale)
.HasColumnName("scale")
.HasDefaultValueSql("((1))");

entity.Property(e => e.Tag)
.HasMaxLength(50)
.IsUnicode(false)
.HasColumnName("tag");

entity.Property(e => e.Title)
.HasMaxLength(50)
.IsUnicode(false)
.HasColumnName("title");

entity.Property(e => e.Type)
.HasMaxLength(50)
.IsUnicode(false)
.HasColumnName("type");

entity.Property(e => e.Width).HasColumnName("width");

entity.Property(e => e.X).HasColumnName("x");

entity.Property(e => e.Y).HasColumnName("y");
});

OnModelCreatingPartial(modelBuilder);
}

partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}



我之前自己写的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using Microsoft.EntityFrameworkCore;
using System.Diagnostics;

namespace CoreWebApi_.EF
{
public class DigitalTwinContext : DbContext
{

public DigitalTwinContext() : base()
{
//这里可配置Context的各种配置选项
}


public DigitalTwinContext(DbContextOptions<DigitalTwinContext> options) : base(options)
{
//这里可配置Context的各种配置选项
}


protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//配置数据库提供程序,并为提供程序配置对应的数据库连接字符串
if (!optionsBuilder.IsConfigured)
{
String connectionStr = StaticHolder.builder.Configuration.GetConnectionString("SqlServerConnection");
Debug.Write("isConfig =false ," + connectionStr);
optionsBuilder.UseSqlServer(connectionStr);
}
else
{
Debug.Write("isConfig =true,");

}


}

}
}


接口里面的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[HttpGet("AddViewFromItem")]
public String AddViewFromItem
(String title, String descript, String tag, int roomID,float scale,String type, float width, float height,int x, int y)
{
using (DigitalTwinContext db = new DigitalTwinContext())
{
//string name, string descript, string tag, int id, int parent
Views view = new();
view.parent = roomID;
view.tag = tag;
view.scale = scale;
view.type = type;
view.width = width;
view.height = height;
view.x = x;
view.y = y;
db.Add(view);
db.SaveChanges();
return "SUCCESS!";
}
}

可以看到我的和他的是有区别的,

另外脚手架定义的是是不分类partial 而且 命名全是大写开头,这将导致我直接作为model返回的json给客户端还需要处理,总感觉有点乱搞的意思。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
namespace CoreWebApi_.Models
{
public partial class Node
{
public string? Name { get; set; }
public string? Descript { get; set; }
public string? Tag { get; set; }
public string? ItemName { get; set; }
public string? ItemDescript { get; set; }
public int Id { get; set; }
public int ParentId { get; set; }
public int? Flag { get; set; }
public int? Parent { get; set; }
}
}


sql创建语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
USE [DigitalTwin]
GO

/****** Object: Table [dbo].[Views] Script Date: 2022/9/8 15:23:57 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Views](
[width] [float] NOT NULL,
[height] [float] NOT NULL,
[x] [float] NOT NULL,
[y] [float] NOT NULL,
[id] [int] IDENTITY(1,1) NOT NULL,
[title] [varchar](50) NULL,
[type] [varchar](50) NULL,
[scale] [float] NOT NULL,
[tag] [varchar](50) NULL,
[data] [varchar](50) NULL,
[parent] [int] NOT NULL,
[parentName] [varchar](50) NULL,
[is3d] [tinyint] NOT NULL
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Views] ADD CONSTRAINT [DF_Views_width] DEFAULT ((0)) FOR [width]
GO

ALTER TABLE [dbo].[Views] ADD CONSTRAINT [DF_Views_height] DEFAULT ((0)) FOR [height]
GO

ALTER TABLE [dbo].[Views] ADD CONSTRAINT [DF_Views_x] DEFAULT ((0)) FOR [x]
GO

ALTER TABLE [dbo].[Views] ADD CONSTRAINT [DF_Views_y] DEFAULT ((0)) FOR [y]
GO

ALTER TABLE [dbo].[Views] ADD CONSTRAINT [DF_Views_scale] DEFAULT ((1)) FOR [scale]
GO

ALTER TABLE [dbo].[Views] ADD CONSTRAINT [DF_Views_parent] DEFAULT ((0)) FOR [parent]
GO

ALTER TABLE [dbo].[Views] ADD CONSTRAINT [DF_Views_is3d] DEFAULT ((0)) FOR [is3d]
GO

image.png

关于主键的问题

解决办法似乎只能重新生成, 同样2个没有设置主键,有一个model 一直提示需要主键,我给他设置主键然后重新生成代码,发现区别是 没有hasNoKey()这行 hasKey("id")加上是不行的,依然错误不过错误又不一样,反正吧,efcore 第三方的东西反人类,有的大神或许认为我应该理解,我是不理解,2个一模一样的的表,我通过create语句比对了,不可能有问题, 两个都没有主键,为啥另外一个就可以插入

最后老哥说一句 ,
有问题无法解决 就直接用脚手架自己生成,解决问题。
既然要主键我就全部设置主键,
重新生成脚手架放到同一个目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
```
C:\Users\惠普\source\repos\CoreWebApi_>dotnet ef dbcontext scaffold --help


Usage: dotnet ef dbcontext scaffold [arguments] [options]

Arguments:
<CONNECTION> The connection string to the database.
<PROVIDER> The provider to use. (E.g. Microsoft.EntityFrameworkCore.SqlServer)

Options:
-d|--data-annotations Use attributes to configure the model (where possible). If omitted, only the fluent API is used.
-c|--context <NAME> The name of the DbContext. Defaults to the database name.
--context-dir <PATH> The directory to put the DbContext file in. Paths are relative to the project directory.
-f|--force Overwrite existing files.
-o|--output-dir <PATH> The directory to put files in. Paths are relative to the project directory.
--schema <SCHEMA_NAME>... The schemas of tables to generate entity types for.
-t|--table <TABLE_NAME>... The tables to generate entity types for.
--use-database-names Use table and column names directly from the database.
--json Show JSON output. Use with --prefix-output to parse programatically.
-n|--namespace <NAMESPACE> The namespace to use. Matches the directory by default.
--context-namespace <NAMESPACE> The namespace of the DbContext class. Matches the directory by default.
--no-onconfiguring Don't generate DbContext.OnConfiguring.
--no-pluralize Don't use the pluralizer.
-p|--project <PROJECT> The project to use. Defaults to the current working directory.
-s|--startup-project <PROJECT> The startup project to use. Defaults to the current working directory.
--framework <FRAMEWORK> The target framework. Defaults to the first one in the project.
--configuration <CONFIGURATION> The configuration to use.
--runtime <RUNTIME_IDENTIFIER> The runtime to use.
--msbuildprojectextensionspath <PATH> The MSBuild project extensions path. Defaults to "obj".
--no-build Don't build the project. Intended to be used when the build is up-to-date.
-h|--help Show help information
-v|--verbose Show verbose output.
--no-color Don't colorize output.
--prefix-output Prefix output with level.


最后 ,配置参数可以让首字母不大写,跟随sql字段 --use-database-names

1
dotnet ef dbcontext scaffold "Data Source=192.168.1.124;Initial Catalog=DigitalTwin;User ID=SA;Password=12345678;Connect Timeout=15" Microsoft.EntityFrameworkCore.SqlServer --use-database-names -f -o  Models