提交 5bf773b6 编写于 作者: 麦壳饼's avatar 麦壳饼

加入Sqlite 和 Oracle 的支持。

上级 9350745e
......@@ -344,3 +344,6 @@ ASALocalRun/
/rabbitmq
/Deployments/zeromq_taos/postgresql
/taos/data
/IoTSharp/TelemetryStorage.db
/IoTSharp/IoTSharp.db
/IoTSharp/health_checks.db
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.Oracle" Version="5.0.1" />
<PackageReference Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="5.0.1" />
<PackageReference Include="EFCore.Sharding.Oracle" Version="3.1.10.6" />
<PackageReference Include="Oracle.EntityFrameworkCore" Version="5.21.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IoTSharp.Data\IoTSharp.Data.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Migrations\" />
</ItemGroup>
</Project>

using EFCore.Sharding;
using IoTSharp.Data;
using IoTSharp.Data.Oracle;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace Microsoft.Extensions.DependencyInjection
{
public static class IoTSharpDataBuilderExtensions
{
public static void ConfigureOracle(this IServiceCollection services, string connectionString, int poolSize, IHealthChecksBuilder checksBuilder, HealthChecksUIBuilder healthChecksUI)
{
services.AddEntityFrameworkOracle();
services.AddSingleton<IDataBaseModelBuilderOptions>( c=> new OracleModelBuilderOptions());
services.AddDbContextPool<ApplicationDbContext>(builder =>
{
builder.UseOracle(connectionString, s => s.MigrationsAssembly("IoTSharp.Data.Oracle"));
builder.UseInternalServiceProvider(services.BuildServiceProvider());
}
, poolSize);
checksBuilder.AddOracle(connectionString);
healthChecksUI.AddInMemoryStorage();
}
public static void UseOracleToSharding(this IShardingBuilder builder, string connectionString, ExpandByDateMode expandBy)
{
builder.AddDataSource(connectionString, ReadWriteType.Read | ReadWriteType.Write, DatabaseType.Oracle);
builder.SetDateSharding<TelemetryData>(nameof(TelemetryData.DateTime), expandBy, DateTime.Now);
}
}
}
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using System;
namespace IoTSharp.Data.Oracle
{
public class OracleModelBuilderOptions : IDataBaseModelBuilderOptions
{
public OracleModelBuilderOptions()
{
}
public IInfrastructure<IServiceProvider> Infrastructure { get; set; }
public void OnModelCreating(ModelBuilder modelBuilder)
{
}
}
}
\ No newline at end of file
......@@ -14,59 +14,7 @@ namespace IoTSharp.Data.SqlServer
public void OnModelCreating(ModelBuilder modelBuilder)
{
//modelBuilder.Entity<TelemetryData>()
//.Property(b => b.DateTime)
//.HasColumnType("timestamp with time zone");
//modelBuilder.Entity<TelemetryData>()
//.Property(b => b.Value_DateTime)
//.HasColumnType("timestamp with time zone");
//modelBuilder.Entity<TelemetryLatest>()
//.Property(b => b.DateTime)
//.HasColumnType("timestamp with time zone");
//modelBuilder.Entity<TelemetryLatest>()
//.Property(b => b.Value_DateTime)
//.HasColumnType("timestamp with time zone");
//modelBuilder.Entity<AttributeLatest>()
//.Property(b => b.DateTime)
//.HasColumnType("timestamp with time zone");
//modelBuilder.Entity<AttributeLatest>()
//.Property(b => b.Value_DateTime)
//.HasColumnType("timestamp with time zone");
//modelBuilder.Entity<TelemetryData>()
//.Property(b => b.Value_Json)
//.HasColumnType("jsonb");
//modelBuilder.Entity<TelemetryData>()
//.Property(b => b.Value_XML)
//.HasColumnType("xml");
//modelBuilder.Entity<AttributeLatest>()
//.Property(b => b.Value_Json)
//.HasColumnType("jsonb");
//modelBuilder.Entity<AttributeLatest>()
//.Property(b => b.Value_XML)
//.HasColumnType("xml");
//modelBuilder.Entity<TelemetryLatest>()
//.Property(b => b.Value_Json)
//.HasColumnType("jsonb");
//modelBuilder.Entity<TelemetryLatest>()
//.Property(b => b.Value_XML)
//.HasColumnType("xml");
//modelBuilder.Entity<AuditLog>()
//.Property(b => b.ActionData)
//.HasColumnType("jsonb");
//modelBuilder.Entity<AuditLog>()
//.Property(b => b.ActionResult)
//.HasColumnType("jsonb");
}
}
}
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.Sqlite" Version="5.0.1" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Sqlite.Storage" Version="5.0.1" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Core" Version="5.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.3" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="5.0.3" />
<PackageReference Include="EFCore.Sharding.SQLite" Version="5.0.0.6" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IoTSharp.Data\IoTSharp.Data.csproj" />
</ItemGroup>
</Project>

using EFCore.Sharding;
using IoTSharp.Data;
using IoTSharp.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace Microsoft.Extensions.DependencyInjection
{
public static class IoTSharpDataBuilderExtensions
{
public static void ConfigureSqlite(this IServiceCollection services, string connectionString, int poolSize, IHealthChecksBuilder checksBuilder, HealthChecksUIBuilder healthChecksUI)
{
services.AddEntityFrameworkSqlite();
services.AddSingleton<IDataBaseModelBuilderOptions>( c=> new SqliteModelBuilderOptions());
services.AddDbContextPool<ApplicationDbContext>(builder =>
{
builder.UseSqlite(connectionString, s => s.MigrationsAssembly("IoTSharp.Data.Sqlite"));
builder.UseInternalServiceProvider(services.BuildServiceProvider());
}
, poolSize);
checksBuilder.AddSqlite(connectionString);
healthChecksUI.AddSqliteStorage("Data Source=health_checks.db");
}
public static void UseSQLiteToSharding(this IShardingBuilder builder, string connectionString, ExpandByDateMode expandBy)
{
builder.AddDataSource(connectionString, ReadWriteType.Read | ReadWriteType.Write, DatabaseType.SQLite);
builder.SetDateSharding<TelemetryData>(nameof(TelemetryData.DateTime), expandBy, DateTime.Now);
}
}
}
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using System;
namespace IoTSharp.Data.Sqlite
{
public class SqliteModelBuilderOptions : IDataBaseModelBuilderOptions
{
public SqliteModelBuilderOptions()
{
}
public IInfrastructure<IServiceProvider> Infrastructure { get; set; }
public void OnModelCreating(ModelBuilder modelBuilder)
{
}
}
}
\ No newline at end of file
......@@ -77,7 +77,7 @@ namespace IoTSharp.Data
SqlServer,
MySql ,
Oracle ,
SQLite
Sqlite
}
[JsonConverter(typeof(StringEnumConverter))]
public enum IdentityType
......
......@@ -18,7 +18,6 @@ namespace IoTSharp.Data
builder.HasIndex(c => new { c.DeviceId });
builder.HasIndex(c => new { c.DeviceId, c.KeyName });
builder.HasIndex(c => new { c.KeyName });
builder.HasIndex(c => new { c.DeviceId, c.KeyName, c.DateTime });
builder.HasKey(c => new { c.DeviceId, c.KeyName, c.DateTime });
builder.Property(t => t.DeviceId)
.IsRequired();
......
......@@ -33,6 +33,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{3048484A-6A46-4E17-825C-D2C59D6D30ED}"
ProjectSection(SolutionItems) = preProject
buildimage.cmd = buildimage.cmd
tools\ef_db_drop.cmd = tools\ef_db_drop.cmd
tools\ef_mg_add.cmd = tools\ef_mg_add.cmd
tools\upgrade_ef.cmd = tools\upgrade_ef.cmd
EndProjectSection
......@@ -49,7 +50,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IoTSharp.Data", "IoTSharp.D
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IoTSharp.Data.MySQL", "IoTSharp.Data.MySQL\IoTSharp.Data.MySQL.csproj", "{233F2C8D-DD4C-49B7-99A2-F3DB5620DEFB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IoTSharp.Data.SqlServer", "IoTSharp.Data.SqlServer\IoTSharp.Data.SqlServer.csproj", "{1B3287BE-4FC5-45C7-BA45-D6A3A92D30C8}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IoTSharp.Data.SqlServer", "IoTSharp.Data.SqlServer\IoTSharp.Data.SqlServer.csproj", "{1B3287BE-4FC5-45C7-BA45-D6A3A92D30C8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IoTSharp.Data.Oracle", "IoTSharp.Data.Oracle\IoTSharp.Data.Oracle.csproj", "{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IoTSharp.Data.Sqlite", "IoTSharp.Data.Sqlite\IoTSharp.Data.Sqlite.csproj", "{C4450C7C-DD38-47A2-90C7-3F774B09CD69}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
......@@ -320,6 +325,46 @@ Global
{1B3287BE-4FC5-45C7-BA45-D6A3A92D30C8}.Release|x64.Build.0 = Release|Any CPU
{1B3287BE-4FC5-45C7-BA45-D6A3A92D30C8}.Release|x86.ActiveCfg = Release|Any CPU
{1B3287BE-4FC5-45C7-BA45-D6A3A92D30C8}.Release|x86.Build.0 = Release|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Debug|ARM.ActiveCfg = Debug|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Debug|ARM.Build.0 = Debug|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Debug|ARM64.Build.0 = Debug|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Debug|x64.ActiveCfg = Debug|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Debug|x64.Build.0 = Debug|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Debug|x86.ActiveCfg = Debug|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Debug|x86.Build.0 = Debug|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Release|Any CPU.Build.0 = Release|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Release|ARM.ActiveCfg = Release|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Release|ARM.Build.0 = Release|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Release|ARM64.ActiveCfg = Release|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Release|ARM64.Build.0 = Release|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Release|x64.ActiveCfg = Release|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Release|x64.Build.0 = Release|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Release|x86.ActiveCfg = Release|Any CPU
{7EE009F2-4B7F-49DB-86D8-ED60D6787DB2}.Release|x86.Build.0 = Release|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Debug|ARM.Build.0 = Debug|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Debug|ARM64.Build.0 = Debug|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Debug|x64.ActiveCfg = Debug|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Debug|x64.Build.0 = Debug|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Debug|x86.ActiveCfg = Debug|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Debug|x86.Build.0 = Debug|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Release|Any CPU.Build.0 = Release|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Release|ARM.ActiveCfg = Release|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Release|ARM.Build.0 = Release|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Release|ARM64.ActiveCfg = Release|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Release|ARM64.Build.0 = Release|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Release|x64.ActiveCfg = Release|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Release|x64.Build.0 = Release|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Release|x86.ActiveCfg = Release|Any CPU
{C4450C7C-DD38-47A2-90C7-3F774B09CD69}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......
......@@ -53,7 +53,7 @@ namespace IoTSharp
return ts.Include(ak => ak.Tenant).Where(ak => ak.Tenant.Id.ToString() == _tenantId);
}
public static Customer GetCustomer(this ApplicationDbContext context, string custid)
=> context.Customer.Include(c => c.Tenant).FirstOrDefault(c => c.Id.ToString() == custid);
=> context.Customer.Include(c => c.Tenant).FirstOrDefault(c => c.Id == Guid.Parse( custid));
public static string GetCustomerId(this ControllerBase controller)
{
......
......@@ -46,9 +46,6 @@
<PackageReference Include="AspNetCore.HealthChecks.System" Version="5.0.1" />
<PackageReference Include="AspNetCore.HealthChecks.UI" Version="5.0.1" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="5.0.1" />
<PackageReference Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="5.0.1" />
<PackageReference Include="AspNetCore.HealthChecks.UI.SQLite.Storage" Version="5.0.1" />
<PackageReference Include="AspNetCore.HealthChecks.Uris" Version="5.0.1" />
<PackageReference Include="AspNetCore.HealthChecks.Network" Version="5.0.1" />
......@@ -93,7 +90,6 @@
<PackageReference Include="MQTTnet.AspNetCoreEx" Version="3.0.14" />
<PackageReference Include="MQTTnet.Extensions.Rpc" Version="3.0.14" />
<PackageReference Include="NetMQ" Version="4.0.1.6" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.2" />
<PackageReference Include="NSwag.AspNetCore" Version="13.10.2" />
<PackageReference Include="ProxyKit" Version="2.3.4" />
<PackageReference Include="Quartz.Serialization.Json" Version="3.2.4" />
......@@ -126,7 +122,10 @@
<None Remove=".gitignore" />
<None Remove="healthchecksdb" />
<None Remove="healthchecksdb-shm" />
<None Remove="health_checks.db" />
<None Remove="IoTSharp.db" />
<None Remove="IoTSharp.xml" />
<None Remove="TelemetryStorage.db" />
<_WebToolingArtifacts Remove="Properties\PublishProfiles\registry.hub.docker.com_iotsharp.pubxml" />
<None Include="..\docs\images\96x96.png">
<Pack>True</Pack>
......@@ -139,7 +138,9 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IoTSharp.Data.MySQL\IoTSharp.Data.MySQL.csproj" />
<ProjectReference Include="..\IoTSharp.Data.Oracle\IoTSharp.Data.Oracle.csproj" />
<ProjectReference Include="..\IoTSharp.Data.PostgreSQL\IoTSharp.Data.PostgreSQL.csproj" />
<ProjectReference Include="..\IoTSharp.Data.Sqlite\IoTSharp.Data.Sqlite.csproj" />
<ProjectReference Include="..\IoTSharp.Data.SqlServer\IoTSharp.Data.SqlServer.csproj" />
<ProjectReference Include="..\IoTSharp.Data\IoTSharp.Data.csproj" />
</ItemGroup>
......
......@@ -98,6 +98,12 @@ namespace IoTSharp
case DataBaseType.SqlServer:
services.ConfigureSqlServer(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
break;
case DataBaseType.Oracle:
services.ConfigureOracle(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
break;
case DataBaseType.Sqlite:
services.ConfigureSqlite(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
break;
case DataBaseType.PostgreSql:
default:
services.ConfigureNpgsql(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
......@@ -206,6 +212,12 @@ namespace IoTSharp
case DataBaseType.SqlServer:
config.UseSqlServerToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
break;
case DataBaseType.Oracle:
config.UseOracleToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
break;
case DataBaseType.Sqlite:
config.UseSQLiteToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
break;
case DataBaseType.PostgreSql:
default:
config.UseNpgsqlToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
......
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
//https://blog.csdn.net/qq_35035078/article/details/88855621
"DataBase": "Oracle",
"ConnectionStrings": {
"IoTSharp": "DATA SOURCE=127.0.0.1:1521/xe;PASSWORD=oracle;PERSIST SECURITY INFO=True;USER ID=SYSTEM;",
"EventBusStore": "mongodb://root:kissme@mongodb:27017",
"TelemetryStorage": "DATA SOURCE=127.0.0.1:1521/xe;PASSWORD=oracle;PERSIST SECURITY INFO=True;USER ID=SYSTEM;",
"EventBusMQ": "amqp://root:kissme@rabbitmq:5672"
},
"JwtKey": "kissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissme",
"JwtExpireHours": 24,
"JwtIssuer": "IoTSharp.Net",
"JwtAudience": "IoTSharp.Net",
"EventBusStore": "InMemory",
"EventBusMQ": "InMemory",
"TelemetryStorage": "Sharding"
}
\ No newline at end of file
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"DataBase": "Sqlite",
"ConnectionStrings": {
"IoTSharp": "Data Source=IoTSharp.db",
"EventBusStore": "mongodb://root:kissme@mongodb:27017",
"TelemetryStorage": "Data Source=TelemetryStorage.db",
"EventBusMQ": "amqp://root:kissme@rabbitmq:5672"
},
"JwtKey": "kissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissmekissme",
"JwtExpireHours": 24,
"JwtIssuer": "IoTSharp.Net",
"JwtAudience": "IoTSharp.Net",
"EventBusStore": "InMemory",
"EventBusMQ": "InMemory",
"TelemetryStorage": "Sharding"
}
\ No newline at end of file
echo off
cls
echo Drop to IoTSharp.Data.%1
set ASPNETCORE_ENVIRONMENT=%1
dotnet ef database drop --context IoTSharp.Data.ApplicationDbContext --startup-project ..\IoTSharp\IoTSharp.csproj --project ..\IoTSharp.Data.%1\IoTSharp.Data.%1.csproj
\ No newline at end of file
echo off
cls
echo Add a migration name is %2 to IoTSharp.Data.%1
cd IoTSharp.Data.%1
set ASPNETCORE_ENVIRONMENT=%1
dotnet ef migrations add %2 --context IoTSharp.Data.ApplicationDbContext --startup-project ..\IoTSharp\IoTSharp.csproj --project ..\IoTSharp.Data.%1\IoTSharp.Data.%1.csproj
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册