diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml
index 299c91e5..8fd2938a 100644
--- a/FreeSql.DbContext/FreeSql.DbContext.xml
+++ b/FreeSql.DbContext/FreeSql.DbContext.xml
@@ -120,6 +120,13 @@
清空状态数据
+
+
+ 根据 lambda 条件删除数据
+
+
+
+
添加
@@ -388,5 +395,14 @@
+
+
+ 批量注入 Repository,可以参考代码自行调整
+
+
+
+
+
+
diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs
new file mode 100644
index 00000000..f3dd26ae
--- /dev/null
+++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/EFCoreAttributeTest.cs
@@ -0,0 +1,110 @@
+using FreeSql.Tests.DataContext.SqlServer;
+using System;
+using System.Data.SqlClient;
+using Xunit;
+
+namespace FreeSql.Tests.DataAnnotations
+{
+ public class EFCoreAttributeTest
+ {
+ IFreeSql fsql => g.sqlserver;
+
+ [Fact]
+ public void TableAttribute()
+ {
+ fsql.CodeFirst.SyncStructure();
+ fsql.CodeFirst.SyncStructure();
+ Assert.Equal("eftesttb_01", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb01)).DbName);
+ Assert.Equal("dbo.eftesttb_02", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb02)).DbName);
+ }
+ [System.ComponentModel.DataAnnotations.Schema.Table("eftesttb_01")]
+ class eftesttb01
+ {
+ public Guid id { get; set; }
+ }
+ [System.ComponentModel.DataAnnotations.Schema.Table("eftesttb_02", Schema = "dbo")]
+ class eftesttb02
+ {
+ public Guid id { get; set; }
+ }
+
+ [Fact]
+ public void MaxLengthAttribute()
+ {
+ fsql.CodeFirst.SyncStructure();
+ Assert.Equal("NVARCHAR(100)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb03)).ColumnsByCs["title"].Attribute.DbType);
+ }
+ class eftesttb03
+ {
+ public Guid id { get; set; }
+ [System.ComponentModel.DataAnnotations.MaxLength(100)]
+ public string title { get; set; }
+ }
+
+ [Fact]
+ public void RequiredAttribute()
+ {
+ fsql.CodeFirst.SyncStructure();
+ Assert.False(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb04)).ColumnsByCs["title"].Attribute.IsNullable);
+ }
+ class eftesttb04
+ {
+ public Guid id { get; set; }
+ [System.ComponentModel.DataAnnotations.Required]
+ public string title { get; set; }
+ }
+
+ [Fact]
+ public void NotMappedAttribute()
+ {
+ fsql.CodeFirst.SyncStructure();
+ Assert.False(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb05)).ColumnsByCsIgnore.ContainsKey("id"));
+ Assert.True(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb05)).ColumnsByCsIgnore.ContainsKey("title"));
+ }
+ class eftesttb05
+ {
+ public Guid id { get; set; }
+ [System.ComponentModel.DataAnnotations.Schema.NotMapped]
+ public string title { get; set; }
+ }
+
+ [Fact]
+ public void ColumnAttribute()
+ {
+ fsql.CodeFirst.SyncStructure();
+ Assert.Equal("title_01", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title1"].Attribute.Name);
+ Assert.Equal("title_02", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title2"].Attribute.Name);
+ Assert.Equal("title_03", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title3"].Attribute.Name);
+
+ Assert.Equal(99, fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title2"].Attribute.Position);
+ Assert.Equal(98, fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title3"].Attribute.Position);
+
+ Assert.Equal("NVARCHAR(255)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title1"].Attribute.DbType);
+ Assert.Equal("NVARCHAR(255)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title2"].Attribute.DbType);
+ Assert.Equal("VARCHAR(100)", fsql.CodeFirst.GetTableByEntity(typeof(eftesttb06)).ColumnsByCs["title3"].Attribute.DbType);
+ }
+ class eftesttb06
+ {
+ public Guid id { get; set; }
+ [System.ComponentModel.DataAnnotations.Schema.Column("title_01")]
+ public string title1 { get; set; }
+ [System.ComponentModel.DataAnnotations.Schema.Column("title_02", Order = 99)]
+ public string title2 { get; set; }
+ [System.ComponentModel.DataAnnotations.Schema.Column("title_03", Order = 98, TypeName = "varchar(100)")]
+ public string title3 { get; set; }
+ }
+
+ [Fact]
+ public void KeyAttribute()
+ {
+ fsql.CodeFirst.SyncStructure();
+ Assert.True(fsql.CodeFirst.GetTableByEntity(typeof(eftesttb07)).ColumnsByCs["title"].Attribute.IsPrimary);
+ }
+ class eftesttb07
+ {
+ public Guid id { get; set; }
+ [System.ComponentModel.DataAnnotations.Key]
+ public string title { get; set; }
+ }
+ }
+}
diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs
index 51a13af8..4a07cecf 100644
--- a/FreeSql/FreeSqlBuilder.cs
+++ b/FreeSql/FreeSqlBuilder.cs
@@ -286,7 +286,7 @@ namespace FreeSql
break;
}
}
- //处理 MaxLength
+ //处理 MaxLength、EFCore 特性
ret.Aop.ConfigEntityProperty += new EventHandler((s, e) =>
{
object[] attrs = null;
@@ -296,17 +296,83 @@ namespace FreeSql
}
catch { }
- var maxlenAttr = attrs?.Where(a => {
+ var dyattr = attrs?.Where(a => {
return ((a as Attribute)?.TypeId as Type)?.Name == "MaxLengthAttribute";
}).FirstOrDefault();
- if (maxlenAttr != null)
+ if (dyattr != null)
{
- var lenProp = maxlenAttr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).FirstOrDefault();
- if (lenProp != null && int.TryParse(string.Concat(lenProp.GetValue(maxlenAttr, null)), out var tryval) && tryval != 0)
+ var lenProp = dyattr.GetType().GetProperties().Where(a => a.PropertyType.IsNumberType()).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();
+ if (dyattr != null)
+ {
+ e.ModifyResult.IsNullable = false;
+ }
+
+ dyattr = attrs?.Where(a => {
+ return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.Schema.NotMappedAttribute";
+ }).FirstOrDefault();
+ if (dyattr != null)
+ {
+ e.ModifyResult.IsIgnore = true;
+ }
+
+ dyattr = attrs?.Where(a => {
+ return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.Schema.ColumnAttribute";
+ }).FirstOrDefault();
+ if (dyattr != null)
+ {
+ var name = dyattr.GetType().GetProperties().Where(a => a.PropertyType == typeof(string) && a.Name == "Name").FirstOrDefault()?.GetValue(dyattr, null)?.ToString();
+ short.TryParse(string.Concat(dyattr.GetType().GetProperties().Where(a => a.PropertyType == typeof(int) && a.Name == "Order").FirstOrDefault()?.GetValue(dyattr, null)), out var order);
+ var typeName = dyattr.GetType().GetProperties().Where(a => a.PropertyType == typeof(string) && a.Name == "TypeName").FirstOrDefault()?.GetValue(dyattr, null)?.ToString();
+
+ if (string.IsNullOrEmpty(name) == false)
+ e.ModifyResult.Name = name;
+ if (order != 0)
+ e.ModifyResult.Position = order;
+ if (string.IsNullOrEmpty(typeName) == false)
+ e.ModifyResult.DbType = typeName;
+ }
+
+ dyattr = attrs?.Where(a => {
+ return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.KeyAttribute";
+ }).FirstOrDefault();
+ if (dyattr != null)
+ {
+ e.ModifyResult.IsPrimary = true;
+ }
+ });
+ //EFCore 特性
+ ret.Aop.ConfigEntity += new EventHandler((s, e) =>
+ {
+ object[] attrs = null;
+ try
+ {
+ attrs = e.EntityType.GetCustomAttributes(false).ToArray(); //.net core 反射存在版本冲突问题,导致该方法异常
+ }
+ catch { }
+
+ var dyattr = attrs?.Where(a => {
+ return ((a as Attribute)?.TypeId as Type)?.FullName == "System.ComponentModel.DataAnnotations.Schema.TableAttribute";
+ }).FirstOrDefault();
+ if (dyattr != null)
+ {
+ var name = dyattr.GetType().GetProperties().Where(a => a.PropertyType == typeof(string) && a.Name == "Name").FirstOrDefault()?.GetValue(dyattr, null)?.ToString();
+ var schema = dyattr.GetType().GetProperties().Where(a => a.PropertyType == typeof(string) && a.Name == "Schema").FirstOrDefault()?.GetValue(dyattr, null)?.ToString();
+ if (string.IsNullOrEmpty(name) == false && string.IsNullOrEmpty(schema) == false)
+ e.ModifyResult.Name = $"{schema}.{name}";
+ else if (string.IsNullOrEmpty(name) == false)
+ e.ModifyResult.Name = name;
+ else if (string.IsNullOrEmpty(schema) == false)
+ e.ModifyResult.Name = $"{schema}.{e.EntityType.Name}";
+ }
});
}