刚开始学ef框架,从网上模仿写的,代码,结果后面执行出了问题。。
发现有一个更快的方法
先配置好环境https://docs.microsoft.com/en-us/ef/core/cli/dotnet
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的命名是根据数据库命名自动识别生成的。
相当规范,于是我删除了我手动写的 一套
主要看看怎么 context写的
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);
}
}
我之前自己写的
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,");
}
}
}
}
接口里面的使用
[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给客户端还需要处理,总感觉有点乱搞的意思。
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创建语句
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
关于主键的问题
解决办法似乎只能重新生成, 同样2个没有设置主键,有一个model 一直提示需要主键,我给他设置主键然后重新生成代码,发现区别是 没有hasNoKey()
这行hasKey("id")
加上是不行的,依然错误不过错误又不一样,反正吧,efcore 第三方的东西反人类,有的大神或许认为我应该理解,我是不理解,2个一模一样的的表,我通过create语句比对了,不可能有问题, 两个都没有主键,为啥另外一个就可以插入
最后老哥说一句 ,
有问题无法解决 就直接用脚手架自己生成,解决问题。
既然要主键我就全部设置主键,
重新生成脚手架放到同一个目录-f
强制覆盖
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
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