Skip to content

Commit

Permalink
Merge pull request #275 from wangyanuter/master
Browse files Browse the repository at this point in the history
wangyanuter 的优化
  • Loading branch information
maikebing authored Oct 22, 2024
2 parents 75d4d89 + 3660540 commit d8b5e3e
Show file tree
Hide file tree
Showing 68 changed files with 4,501 additions and 326 deletions.
24 changes: 24 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/src/Example/bin/Debug/net7.0/Example.dll",
"args": [],
"cwd": "${workspaceFolder}/src/Example",
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}
41 changes: 41 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/EFCore.Taos.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/EFCore.Taos.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/EFCore.Taos.sln"
],
"problemMatcher": "$msCompile"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Update;
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.EntityFrameworkCore.Metadata;
using System.Linq;
using Microsoft.EntityFrameworkCore.Query.Internal;

// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection
Expand Down Expand Up @@ -52,6 +55,7 @@ public static IServiceCollection AddEntityFrameworkTaos([NotNull] this IServiceC
var builder = new EntityFrameworkRelationalServicesBuilder(serviceCollection)
.TryAdd<LoggingDefinitions, TaosLoggingDefinitions>()
.TryAdd<IDatabaseProvider, DatabaseProvider<TaosOptionsExtension>>()
.TryAdd<IDatabase, TaosDatabase>()//没有用。。
.TryAdd<IRelationalTypeMappingSource, TaosTypeMappingSource>()
.TryAdd<ISqlGenerationHelper, TaosSqlGenerationHelper>()
.TryAdd<IMigrationsAnnotationProvider, TaosMigrationsAnnotationProvider>()
Expand All @@ -63,15 +67,34 @@ public static IServiceCollection AddEntityFrameworkTaos([NotNull] this IServiceC
.TryAdd<IMigrationsSqlGenerator, TaosMigrationsSqlGenerator>()
.TryAdd<IRelationalDatabaseCreator, TaosDatabaseCreator>()
.TryAdd<IHistoryRepository, TaosHistoryRepository>()
.TryAdd<IBatchExecutor, TaosBatchExecutor>()
.TryAdd<ICommandBatchPreparer, TaosCommandBatchPreparer>()
.TryAdd<IQueryContextFactory, TaosQueryContextFactory>()
.TryAdd<IModelCustomizer, TaosModelCustomizer>()
.TryAdd<IRelationalCommandBuilderFactory, TaosEFCommandBuilderFactory>()

// New Query Pipeline
.TryAdd<IMethodCallTranslatorProvider, TaosMethodCallTranslatorProvider>()
.TryAdd<IMemberTranslatorProvider, TaosMemberTranslatorProvider>()
.TryAdd<IQuerySqlGeneratorFactory, TaosQuerySqlGeneratorFactory>()
.TryAdd<IQueryableMethodTranslatingExpressionVisitorFactory, TaosQueryableMethodTranslatingExpressionVisitorFactory>()
.TryAdd<IRelationalSqlTranslatingExpressionVisitorFactory, TaosSqlTranslatingExpressionVisitorFactory>()
.TryAdd<IRelationalParameterBasedSqlProcessorFactory, TaosParameterBasedSqlProcessorFactory>()

.TryAddProviderSpecificServices(
b => b.TryAddScoped<ITaosRelationalConnection, TaosRelationalConnection>());
b => b
.TryAddScoped<IQueryProvider, TaosQueryProvider>()
.TryAddScoped<ITaosRelationalConnection, TaosRelationalConnection>()
.TryAddScoped<IRelationalCommandBuilder, TaosEFCommandBuilder>()//配置无效,未创建
.TryAddScoped<IRelationalCommand, TaosEFCommand>()//配置无效,未创建
)

.TryAdd<ISqlExpressionFactory, TaosSqlExpressionFactory>()//表达式的生成
.TryAdd<IRelationalQueryStringFactory, TaosRelationalQueryStringFactory>()



;

builder.TryAddCoreServices();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;

namespace IoTSharp.EntityFrameworkCore.Taos.Infrastructure.Internal
{
public class TaosModelCustomizer : RelationalModelCustomizer
{
public TaosModelCustomizer(ModelCustomizerDependencies dependencies) : base(dependencies)
{
}

public override void Customize(ModelBuilder modelBuilder, DbContext context)
{
var taostabs = context.GetType().GetProperties().Where(w =>
{
var isDbSet = w.PropertyType.IsGenericType && w.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>);
if (isDbSet)
{
isDbSet &= w.PropertyType.GenericTypeArguments.All(a => a.GetCustomAttribute<TaosAttribute>() != null);
}
return isDbSet;
}).Select(s => s.PropertyType).ToList();
foreach (var tab in taostabs)
{
foreach (var arg in tab.GenericTypeArguments)
{
modelBuilder.Entity(arg);
}
}
base.Customize(modelBuilder, context);

}
}
}
10 changes: 5 additions & 5 deletions src/EFCore.Taos.Core/IoTSharp.EntityFrameworkCore.Taos.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@
<Compile Include="..\Shared\*.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.3">
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="7.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.3" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.10" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="7.0.0" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\docs\logo.png">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) Maikebing. All rights reserved.
// Licensed under the MIT License, See License.txt in the project root for license information.

using System.Reflection;

using IoTSharp.EntityFrameworkCore.Taos;

using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal;

// ReSharper disable once CheckNamespace
namespace Microsoft.EntityFrameworkCore.Metadata.Conventions
{
public class TaosAttributeConvention : EntityTypeAttributeConventionBase<TaosAttribute>
{
public TaosAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) : base(dependencies)
{
}

protected override void ProcessEntityTypeAdded(IConventionEntityTypeBuilder entityTypeBuilder, TaosAttribute attribute, IConventionContext<IConventionEntityTypeBuilder> context)
{
var tableName = attribute.TableName;
if (string.IsNullOrWhiteSpace(tableName))
{
var type = entityTypeBuilder.Metadata.ClrType;
tableName = type.Name;
}

entityTypeBuilder.ToTable(tableName, fromDataAnnotation: true);
}
public override void ProcessEntityTypeAdded(IConventionEntityTypeBuilder entityTypeBuilder, IConventionContext<IConventionEntityTypeBuilder> context)
{
var type = entityTypeBuilder.Metadata.ClrType;

var attributes = type.GetCustomAttributes<TaosAttribute>(true);
foreach (var attribute in attributes)
{
ProcessEntityTypeAdded(entityTypeBuilder, attribute, context);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// Copyright (c) Maikebing. All rights reserved.
// Licensed under the MIT License, See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Reflection;

using IoTSharp.EntityFrameworkCore.Taos;

using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata.Internal;

// ReSharper disable once CheckNamespace
namespace Microsoft.EntityFrameworkCore.Metadata.Conventions
{
/// <summary>
/// IPropertyAddedConvention, IConvention, IPropertyFieldChangedConvention
/// </summary>
public class TaosColumnAttributePropertyAttributeConvention : PropertyAttributeConventionBase<TaosColumnAttribute>, IModelFinalizingConvention, IEntityTypeAddedConvention, IEntityTypeBaseTypeChangedConvention
{
public TaosColumnAttributePropertyAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) : base(dependencies)
{
}

public void ProcessEntityTypeAdded(IConventionEntityTypeBuilder entityTypeBuilder, IConventionContext<IConventionEntityTypeBuilder> context)
{

var entityType = entityTypeBuilder.Metadata;
var taosAtt = entityType.ClrType.GetCustomAttribute<TaosAttribute>();
var members = entityType.GetRuntimeProperties().Values.Cast<MemberInfo>()
//.Concat(entityType.GetRuntimeFields().Values)
.Select(s =>
{
var pmeta = entityType.FindProperty(s);
var attr = s.GetCustomAttribute<TaosColumnAttribute>();
if (pmeta == null && (attr != null && !attr.IsSubTableName))
{
pmeta = entityType.AddProperty(s);
}
return (Menber: s, Attr: attr, Meta: pmeta);
});
if (taosAtt.IsSuperTable)
{
var haveSubTableName = members.Where(w => w.Attr != null && w.Attr.IsSubTableName).Count() > 0;
if (!haveSubTableName)
{
throw new Exception("super table model need subtable name property");
}
}

foreach (var m in members)
{
if (m.Attr.IsSubTableName)
{
entityTypeBuilder.Ignore(m.Menber.GetSimpleMemberName(), fromDataAnnotation: true);
}

}
var keyMembers = members.Where(w => w.Attr != null && w.Attr.ColumnType == TaosDataType.TIMESTAMP || w.Attr.IsTag);
if (keyMembers != null && keyMembers.Count() > 0)
{
var keyProps = keyMembers.Select(s =>
{
//var name = string.IsNullOrWhiteSpace(s.Attr.ColumnName) ? s.Menber.Name : s.Attr.ColumnName;
return entityTypeBuilder.Metadata.FindProperty(s.Menber);
}).Where(w => w != null).ToList();

if (keyProps.Count > 0)
{
entityTypeBuilder.PrimaryKey(keyProps, true);
}
}


}


public void ProcessEntityTypeBaseTypeChanged(IConventionEntityTypeBuilder entityTypeBuilder, IConventionEntityType newBaseType, IConventionEntityType oldBaseType, IConventionContext<IConventionEntityType> context)
{
if (oldBaseType == null)
{
return;
}

}

protected override void ProcessPropertyAdded(IConventionPropertyBuilder propertyBuilder, TaosColumnAttribute attribute, MemberInfo clrMember, IConventionContext context)
{

var property = propertyBuilder.Metadata;
//var member = property.GetIdentifyingMemberInfo();



if (!string.IsNullOrWhiteSpace(attribute?.ColumnName))
{
if (attribute?.ColumnName == "value")
{
throw new Exception("column name value not allow");
}
propertyBuilder.HasColumnName(attribute.ColumnName, true);
}
else if (property.Name == "value")
{
throw new Exception("column name value not allow");
}

propertyBuilder.HasColumnType(attribute.ColumnType.ToString(), true);
if (attribute.ColumnLength > 0)
{
propertyBuilder.HasMaxLength(attribute.ColumnLength, true);
}
//switch (attribute.ColumnType)
//{
// case TaosDataType.BINARY:
// case TaosDataType.NCHAR:
// case TaosDataType.VARCHAR:
// case TaosDataType.GEOMETRY:
// case TaosDataType.VARBINARY:
// propertyBuilder.HasColumnType($"{attribute.ColumnType}({attribute.ColumnLength})", true);
// break;
// default:
// propertyBuilder.HasColumnType(attribute.ColumnType.ToString(), true);
// break;
//}
if (attribute.IsTag)
{
propertyBuilder.IsRequired(true, true);
}

}

public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
{


}


}
}
Loading

0 comments on commit d8b5e3e

Please sign in to comment.