Skip to content

Instantly share code, notes, and snippets.

@f7q
Last active January 15, 2018 21:42
Show Gist options
  • Save f7q/0ebd242bb2e3c5b4c0eab0658a5cfa51 to your computer and use it in GitHub Desktop.
Save f7q/0ebd242bb2e3c5b4c0eab0658a5cfa51 to your computer and use it in GitHub Desktop.
Sample
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Infrastructure;
using OptimicLock.Models;
namespace OptimicLock
{
public class AppDbContextFactory : IDesignTimeDbContextFactory<AppDbContext>
{
public AppDbContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<AppDbContext>();
optionsBuilder.UseNpgsql("User Id=postgres;Password=;Host=localhost;Port=5432;Database=mydb;"); ;
//return new AppDbContext(optionsBuilder.Options);
return new AppDbContext();
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace OptimicLock.Models
{
// DBコンテキスト
public class AppDbContext : DbContext
{
//public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
public AppDbContext(
//DbContextOptions<AppDbContext> options,
bool tracking = false)
//: base(options)
{
//options = new DbContextOptionsBuilder<AppDbContext>();
ChangeTracker.QueryTrackingBehavior = tracking
? QueryTrackingBehavior.TrackAll
: QueryTrackingBehavior.NoTracking;
//return base(options);
}
/*
public AppDbContext(bool tracking = false)
{
ChangeTracker.QueryTrackingBehavior = tracking
? QueryTrackingBehavior.TrackAll
: QueryTrackingBehavior.NoTracking;
}
*/
public DbSet<Monster> Monster { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
/*
var connectionString = new SqlConnectionStringBuilder
{
DataSource = ".",
InitialCatalog = "Test",
IntegratedSecurity = true,
}.ToString();
optionsBuilder.UseSqlServer(connectionString);
*/
optionsBuilder.UseNpgsql("User Id=postgres;Password=;Host=localhost;Port=5432;Database=mydb;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Monster>().ToTable(nameof(Monster));
// Fluent APIの場合
// Timestamp属性の代わりにこちらでも
/*
modelBuilder.Entity<Monster>()
.Property(monster => monster.Version)
.ValueGeneratedOnAddOrUpdate()
.IsConcurrencyToken();
*/
modelBuilder.Entity<Monster>(b =>
{
b.Property<uint>("xmin")
.HasColumnType("xid")
.ValueGeneratedOnAddOrUpdate()
.IsConcurrencyToken();
});
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace OptimicLock
{
// ロガープロバイダー
public class AppLoggerProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName)
{
if (string.Equals(categoryName, DbLoggerCategory.Database.Command.Name))
{
return new ConsoleLogger();
}
return NullLogger.Instance;
}
public void Dispose()
{
}
// ロガー
private class ConsoleLogger : ILogger
{
public IDisposable BeginScope<TState>(TState state) => null;
// 情報レベル以上のログを有効にする
public bool IsEnabled(LogLevel logLevel) => logLevel >= LogLevel.Information;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception,
Func<TState, Exception, string> formatter)
{
Console.WriteLine(formatter(state, exception));
Console.WriteLine("---");
}
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="1.7.14" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.1">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.1" PrivateAssets="All" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.1">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.1" />
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.1" />
</ItemGroup>
</Project>
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using OptimicLock.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Extensions;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Z.EntityFramework.Plus;
namespace OptimicLock.Service
{
public class LoopService
{
public AppDbContext Context { get; set; }
public LoopService(AppDbContext context)
{
this.Context = context;
}
public async Task StartLoopJob()
{
var sw = new System.Diagnostics.Stopwatch();
sw.Start();
using (var transaction = this.Context.Database.BeginTransaction())
{
try
{
var count = this.Context.Monster.Count();
//System.Console.ReadLine();
List<Monster> items = this.Context.Monster.OrderBy(x => x.Id).ToList();
//System.Console.ReadLine();
//var digit = (count == 0) ? 1 : ((int)Math.Log10(count) + 1);
foreach (var (value, index) in items.Select((value, index) => (value, index)))
{
if (index % 10 == 1)
{
decimal i = index + 1;
decimal d_per = Math.Ceiling((i / count) * (90));
int per = (int)d_per;
value.Name = per.ToString() + "% = ";// + Guid.NewGuid().ToString();
this.Context.Entry(value).State = EntityState.Modified;
this.Context.SaveChanges();
}
}
this.Context.SaveChanges();
transaction.Commit();
}
catch(Exception)
{
transaction.Rollback();
}
finally
{
transaction.Dispose();
}
}
sw.Stop();
TimeSpan ts = sw.Elapsed;
Console.WriteLine($" {ts}");
Console.WriteLine($" {ts.Hours}時間 {ts.Minutes}分 {ts.Seconds}秒 {ts.Milliseconds}ミリ秒");
Console.WriteLine($" {sw.ElapsedMilliseconds}ミリ秒");
}
public async Task StartBulkUpdate()
{
var sw = new System.Diagnostics.Stopwatch();
sw.Start();
using (var transaction = this.Context.Database.BeginTransaction())
{
try
{
var count = this.Context.Monster.Count();
//System.Console.ReadLine();
List<Monster> items = this.Context.Monster.OrderBy(x => x.Id).ToList();
//System.Console.ReadLine();
//var digit = (count == 0) ? 1 : ((int)Math.Log10(count) + 1);
this.Context.Monster.Where(x => x.Id % 10 == 0)
.Update(x => new Monster() { Name = "abc"+ Guid.NewGuid().ToString() });
this.Context.SaveChanges();
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
}
finally
{
transaction.Dispose();
}
}
sw.Stop();
TimeSpan ts = sw.Elapsed;
Console.WriteLine($" {ts}");
Console.WriteLine($" {ts.Hours}時間 {ts.Minutes}分 {ts.Seconds}秒 {ts.Milliseconds}ミリ秒");
Console.WriteLine($" {sw.ElapsedMilliseconds}ミリ秒");
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace OptimicLock.Models
{
// モンスター
public class Monster
{
public int Id { get; set; }
public string Name { get; set; }
public uint xmin { get; set; }
}
}
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Npgsql.EntityFrameworkCore.PostgreSQL.Storage;
using Npgsql.EntityFrameworkCore.PostgreSQL;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Logging.Internal;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore.Infrastructure;
using OptimicLock.Models;
using System.Collections.Generic;
using OptimicLock.Service;
namespace OptimicLock
{
public class Program
{
public static void Main(string[] args)
{
using (var dbContext = new AppDbContext())
{
dbContext.Database.EnsureCreated();
// ロガープロバイダーを設定
var serviceProvider = dbContext.GetInfrastructure();
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
loggerFactory.AddProvider(new AppLoggerProvider());
}
IServiceCollection collection = new ServiceCollection();
collection.AddTransient<AppDbContext>();
collection.AddTransient<LoopService>();
var provider = collection.BuildServiceProvider();
using (var di = provider.CreateScope())
{
var loop = di.ServiceProvider.GetRequiredService<LoopService>();
//loop.StartLoopJob().Wait();
loop.StartBulkUpdate().Wait();
}
Console.ReadLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment