Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

建议能结合EF Core的一些特性来弄 #4

Closed
qcjxberin opened this issue Jan 28, 2019 · 32 comments
Closed

建议能结合EF Core的一些特性来弄 #4

qcjxberin opened this issue Jan 28, 2019 · 32 comments

Comments

@qcjxberin
Copy link

比如能识别下面的映射表及映射主键Id

` ///


/// 映射表
///

protected override void MapTable( EntityTypeBuilder builder ) {
builder.ToTable( "cg_kssqbs" );
}

    /// <summary>
    /// 映射属性
    /// </summary>
    protected override void MapProperties( EntityTypeBuilder<CgKssqbs> builder ) {
        //Id编号
        builder.Property(t => t.Id)
            .HasColumnName("kssqbs_id");
    }`
@2881099
Copy link
Collaborator

2881099 commented Jan 28, 2019

意见收到,现在过年期间,年后向您请教

@qcjxberin
Copy link
Author

有新的进展了吗?

@2881099
Copy link
Collaborator

2881099 commented Feb 14, 2019

@2881099
Copy link
Collaborator

2881099 commented Feb 14, 2019

using FreeSql.DataAnnotations;
using Xunit;

namespace FreeSql.Tests.DataAnnotations {

public class g {

	public static IFreeSql mysql = new FreeSql.FreeSqlBuilder()
		.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
		.UseAutoSyncStructure(true)
		.UseMonitorCommand(
			cmd => {
				Trace.WriteLine(cmd.CommandText);
			}, //监听SQL命令对象,在执行前
			(cmd, traceLog) => {
				Console.WriteLine(traceLog);
			}) //监听SQL命令对象,在执行后
		.UseLazyLoading(true)
		.Build();
	}

	public class FluentTest {
		[Fact]
		public void Fluent() {
			g.mysql.CodeFirst
				.ConfigEntity<TestFluenttb1>(a => {
					a.Name("xxdkdkdk1").SelectFilter("a.Id22 > 0");
					a.Property(b => b.Id).Name("Id22").IsIdentity(true);
					a.Property(b => b.name).DbType("varchar(100)").IsNullable(true);
				})
				.ConfigEntity<TestFluenttb2>(a => {
					a.Name("xxdkdkdk2").SelectFilter("a.Idx > 0");
					a.Property(b => b.Id).Name("Id22").IsIdentity(true);
					a.Property(b => b.name).DbType("varchar(100)").IsNullable(true);
				});

			var ddl1 = g.mysql.CodeFirst.GetComparisonDDLStatements<TestFluenttb1>();
			var ddl2 = g.mysql.CodeFirst.GetComparisonDDLStatements<TestFluenttb2>();

			var t1id = g.mysql.Insert<TestFluenttb1>().AppendData(new TestFluenttb1 { }).ExecuteIdentity();
			var t1 = g.mysql.Select<TestFluenttb1>(t1id).ToOne();

			var t2lastId = g.mysql.Select<TestFluenttb2>().Max(a => a.Id);
			var t2affrows = g.mysql.Insert<TestFluenttb2>().AppendData(new TestFluenttb2 { Id = t2lastId + 1 }).ExecuteAffrows();
			var t2 = g.mysql.Select<TestFluenttb2>(t2lastId + 1).ToOne();
		}
	}

	class TestFluenttb1 {
		public int Id { get; set; }

		public string name { get; set; } = "defaultValue";
	}

	[Table(Name = "cccccdddwww")]
	class TestFluenttb2 {
		[Column(Name = "Idx", IsPrimary = true, IsIdentity = false)]
		public int Id { get; set; }

		public string name { get; set; } = "defaultValue";
	}
}

这是测试代码,目前已经发布了

@qcjxberin
Copy link
Author

qcjxberin commented Feb 14, 2019

`///


/// 映射表
///

protected override void MapTable( EntityTypeBuilder builder ) {
builder.ToTable( "auth" );
}

    /// <summary>
    /// 映射属性
    /// </summary>
    protected override void MapProperties( EntityTypeBuilder<Auth> builder ) {
        //Id编号
        builder.Property(t => t.Id)
            .HasColumnName("id");
    }`

@2881099
Copy link
Collaborator

2881099 commented Feb 14, 2019

目前设定方法名和Attribute是一样的,看上去比较尬,哈哈

@qcjxberin
Copy link
Author

有办法改进支持一下吗?我想将你的这个框架和我们现在的系统结合起来用

@qcjxberin
Copy link
Author

具体你可以看一下Util这个开源项目

@2881099
Copy link
Collaborator

2881099 commented Feb 14, 2019

正好昨天在看util

image

是兼容这一段吗?

@qcjxberin
Copy link
Author

是的,因为目前实体没法共用,会提示找不到字段

@2881099
Copy link
Collaborator

2881099 commented Feb 14, 2019

可否方便发一些实体+map demo 作参考

@2881099
Copy link
Collaborator

2881099 commented Feb 14, 2019

邮箱:[email protected]

@qcjxberin
Copy link
Author

我们这主要也就是主键Id字段的名字会不一样。你可以直接在Util的Demo基础上实现功能就能满足需求了。

@2881099
Copy link
Collaborator

2881099 commented Feb 14, 2019

using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;

namespace FreeSql.Extensions.EFCoreModelBuilder {

	public static class CodeFirstExtensions {

		public static void ConfigEntity(this ICodeFirst codeFirst, ModelBuilder modelBuilder) {

			foreach (var type in modelBuilder.Model.GetEntityTypes()) {

				codeFirst.ConfigEntity(type.ClrType, a => {

					//表名
					var relationalTableName = type.FindAnnotation("Relational:TableName");
					if (relationalTableName != null) {
						a.Name(relationalTableName.Value?.ToString() ?? type.ClrType.Name);
					}

					foreach (var prop in type.GetProperties()) {

						var freeProp = a.Property(prop.Name);

						//列名
						var relationalColumnName = prop.FindAnnotation("Relational:ColumnName");
						if (relationalColumnName != null) {

							freeProp.Name(relationalColumnName.Value?.ToString() ?? prop.Name);
						}

						//主键
						freeProp.IsPrimary(prop.IsPrimaryKey());

						//自增
						freeProp.IsIdentity(prop.GetAnnotations().Where(z => 
							z.Name == "SqlServer:ValueGenerationStrategy" && z.Value.ToString().Contains("IdentityColumn") //sqlserver 自增
						).Any());

						//可空
						freeProp.IsNullable(prop.AfterSaveBehavior != Microsoft.EntityFrameworkCore.Metadata.PropertySaveBehavior.Throw);

						//类型
						var relationalColumnType = prop.FindAnnotation("Relational:ColumnType");
						if (relationalColumnType != null) {

							var dbType = relationalColumnType.ToString();

							if (!string.IsNullOrEmpty(dbType)) {

								var maxLength = prop.FindAnnotation("MaxLength");
								if (maxLength != null)
									dbType += $"({maxLength})";

								freeProp.DbType(dbType);
							}
						}
					}
				});
			}
		}
	}
}

你先看看这段代码。使用的是扩展方法,意图将 EF ModelBuilder 对象直接配置为 FreeSql 的实体。
是否可行?

更新日志:
https://github.com/2881099/FreeSql/wiki/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97

代码:
FreeSql.Extensions.EFCoreModelBuilder/CodeFirstExtensions.cs

2881099 pushed a commit that referenced this issue Feb 14, 2019
- 增加 FreeSql.Extensions.EFCoreModelBuilder 扩展库,现实与 EFCore 实体共存;
- 增加 FreeSql.RESTful.Demo 示例项目;
@2881099
Copy link
Collaborator

2881099 commented Feb 15, 2019

https://www.cnblogs.com/kellynic/p/10384165.html
在 EFCore 定义的实体中进行 FreeSql 开发

@qcjxberin
Copy link
Author

我看看

@qcjxberin
Copy link
Author

还需要针对每个实体来做下面这种配置吗?

fsql.CodeFirst
.ConfigEntity(a => {
a.Name("xxdkdkdk1").SelectFilter("a.Id22 > 0");
a.Property(b => b.Id).Name("Id22").IsIdentity(true);
a.Property(b => b.name).DbType("varchar(100)").IsNullable(true);
})
.ConfigEntity(a => {
a.Name("xxdkdkdk2").SelectFilter("a.Idx > 0");
a.Property(b => b.Id).Name("Id22").IsIdentity(true);
a.Property(b => b.name).DbType("varchar(100)").IsNullable(true);
});

@2881099
Copy link
Collaborator

2881099 commented Feb 16, 2019

不需要啊,在Ef fuentapi 或onmodelcreating 配置

@qcjxberin
Copy link
Author

有没有具体的Demo?

@2881099
Copy link
Collaborator

2881099 commented Feb 16, 2019

v0.0.14

  • ICodeFirst.ConfigEntity 可更新实体配置已缓存的数据;
  • 防止同连接字符串被IFreeSql使用多次,发生连接池溢出bug(ado.net连接池原理,减少解释成本);
  • 增加 efcore_to_freesql 示例项目,现实与 EFCore 实体共存;

示例请见源码:
https://github.com/2881099/FreeSql/tree/master/Examples/efcore_to_freesql

在 Startup.cs 测试的,请看注释执行的SQL语句。如果EF实体配置过映射,在执行任意EF操作后将配置同步至FreeSql中。

@2881099
Copy link
Collaborator

2881099 commented Feb 16, 2019

所有 EFCore DBContext 继承 BaseDBContext

public class BaseDBContext : DbContext {

	public static IFreeSql Fsql { get; set; }

	protected override void OnModelCreating(ModelBuilder modelBuilder) {
		base.OnModelCreating(modelBuilder);
		Fsql.CodeFirst.ConfigEntity(modelBuilder.Model); //同步配置
	}
	protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
		optionsBuilder.UseSqlite(@"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10");
	}
}

@qcjxberin
Copy link
Author

和Util的一起使用有冲突,会导致原本的不可用。

@2881099
Copy link
Collaborator

2881099 commented Feb 16, 2019

方便发个冲突小demo我的邮箱吗,[email protected]

@qcjxberin
Copy link
Author

晚点我发个Demo给你看一下。

@qcjxberin
Copy link
Author

你可以试一下那些表名或者字段名带下划线的,一起使用的时候会导致映射的表名下拉线没有了,感觉好像没有起作用一样的。

@2881099
Copy link
Collaborator

2881099 commented Feb 26, 2019

image

测试了,下划线不会去掉啊。建议你还是发个demo给我

@qcjxberin
Copy link
Author

这样直接用肯定没问题,你结合一下util使用试试。

@2881099
Copy link
Collaborator

2881099 commented Feb 26, 2019

整个可运行的demo呀,我不知道util的使用习惯。

@qcjxberin
Copy link
Author

我看了一下你的Demo,需要在Startup里配置一次数据库链接,也还需要在BaseDBContext里配置一次链接吗?

@2881099
Copy link
Collaborator

2881099 commented Apr 5, 2019

只要配置一次就行,要么starup,或者basedbcontext那里

@qcjxberin
Copy link
Author

看一下QQ

@qcjxberin
Copy link
Author

能不能弄个单独只是基于basedbcontext的demo,我看了一下你的案例更多的是基于startup的

2881099 pushed a commit that referenced this issue Dec 29, 2019
- 增加 ColumnAttribute 属性 InsertValueSql,插入数据的时候指定用 sql 值;
2881099 pushed a commit that referenced this issue Apr 15, 2020
 - 移除 FreeSql.Extensions.EfCoreFluentApi,功能移至 FreeSql.DbContext;
@2881099 2881099 closed this as completed May 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants