From facfafa9ef4f0dc164b90638abc6537b43cf7abe Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 16 Jul 2020 18:02:24 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20EFCore=20DatabaseGener?= =?UTF-8?q?atedAttribute=20=E7=89=B9=E6=80=A7=E7=9A=84=E6=94=AF=E6=8C=81?= =?UTF-8?q?=20#378=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataAnnotations/EFCoreAttributeTest.cs | 30 +- FreeSql/FreeSql.xml | 312 ++++++++++-------- FreeSql/FreeSqlBuilder.cs | 46 ++- 3 files changed, 230 insertions(+), 158 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs index b3868ad2..c1e549ac 100644 --- a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs @@ -33,13 +33,23 @@ namespace FreeSql.Tests.DataAnnotations { fsql.CodeFirst.SyncStructure(); Assert.Equal("NVARCHAR(100)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb03)).ColumnsByCs["title"].Attribute.DbType); - Assert.Equal("NVARCHAR(101)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb03)).ColumnsByCs["title2"].Attribute.DbType); } class eftesttb03 { public Guid id { get; set; } [System.ComponentModel.DataAnnotations.MaxLength(100)] public string title { get; set; } + } + + [Fact] + public void StringLengthAttribute() + { + fsql.CodeFirst.SyncStructure(); + Assert.Equal("NVARCHAR(101)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb033)).ColumnsByCs["title2"].Attribute.DbType); + } + class eftesttb033 + { + public Guid id { get; set; } [System.ComponentModel.DataAnnotations.StringLength(101)] public string title2 { get; set; } } @@ -109,5 +119,23 @@ namespace FreeSql.Tests.DataAnnotations [System.ComponentModel.DataAnnotations.Key] public string title { get; set; } } + + [Fact] + public void DatabaseGeneratedAttribute() + { + fsql.CodeFirst.SyncStructure(); + Assert.True(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb08)).ColumnsByCs["id"].Attribute.IsPrimary); + Assert.True(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb08)).ColumnsByCs["id"].Attribute.IsIdentity); + Assert.False(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb08)).ColumnsByCs["createtime"].Attribute.CanInsert); + Assert.False(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb08)).ColumnsByCs["createtime"].Attribute.CanUpdate); + } + class eftesttb08 + { + [System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedAttribute(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)] + public int id { get; set; } + public string title { get; set; } + [System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedAttribute(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Computed)] + public string createtime { get; set; } + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e0ffd602..90034009 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2511,137 +2511,6 @@ - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - - - - - - - - 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) - - - - - - 可自定义解析表达式 @@ -3291,12 +3160,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3367,12 +3230,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 @@ -4028,3 +3885,172 @@ +xpression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据 + MySql: on duplicate key update + PostgreSQL: on conflict do update + SqlServer: merge into + Oracle: merge into + Sqlite: replace into + Dameng: merge into + 注意:还可以使用 FreeSql.Repository 的 InsertOrUpdate 方法 + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 查询数据 + + + + + + + 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 删除数据 + + + + + + + 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步) + v1.5.0 关闭了线程事务超时自动提交的机制 + + 事务体 () => {} + + + + 开启事务(不支持异步) + v1.5.0 关闭了线程事务超时自动提交的机制 + + + 事务体 () => {} + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + + diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 5f7b6056..e4ff315f 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -326,20 +326,6 @@ namespace FreeSql } } - dyattr = attrs?.Where(a => { - return ((a as Attribute)?.TypeId as Type)?.Name == "StringLengthAttribute"; - }).FirstOrDefault(); - if (dyattr != null) - { - var lenProps = dyattr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).ToArray(); - var lenProp = lenProps.Length == 1 ? lenProps.FirstOrDefault() : lenProps.Where(a => a.Name == "MaximumLength").FirstOrDefault(); - if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(dyattr, null)), out var tryval) && tryval != 0) - { - e.ModifyResult.StringLength = tryval; - } - } - - dyattr = attrs?.Where(a => { return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.RequiredAttribute"; }).FirstOrDefault(); @@ -380,6 +366,38 @@ namespace FreeSql { e.ModifyResult.IsPrimary = true; } + + dyattr = attrs?.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.StringLengthAttribute"; + }).FirstOrDefault(); + if (dyattr != null) + { + var lenProps = dyattr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).ToArray(); + var lenProp = lenProps.Length == 1 ? lenProps.FirstOrDefault() : lenProps.Where(a => a.Name == "MaximumLength").FirstOrDefault(); + if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(dyattr, null)), out var tryval) && tryval != 0) + { + e.ModifyResult.StringLength = tryval; + } + } + + //https://github.com/dotnetcore/FreeSql/issues/378 + dyattr = attrs?.Where(a => { + return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedAttribute"; + }).FirstOrDefault(); + if (dyattr != null) + { + switch(string.Concat(dyattr.GetType().GetProperty("DatabaseGeneratedOption")?.GetValue(dyattr, null))) + { + case "Identity": + case "1": + e.ModifyResult.IsIdentity = true; + break; + default: + e.ModifyResult.CanInsert = false; + e.ModifyResult.CanUpdate = false; + break; + } + } }); //EFCore 特性 ret.Aop.ConfigEntity += new EventHandler((s, e) =>