アーカイブ

Archive for the ‘ASP.NET’ Category

EntityFramework のマイグレーションで複数のContextが含まれる場合は -c (-context)オプションを利用する。

Dataプロジェクトに
AppDbContext と AuthDbContext という複数のコンテキストがあった場合、普通にdotnet ef migrations add とかするとこんな感じで怒られるので

More than one DbContext was found. Specify which one to use. Use the ‘-Context’ parameter for PowerShell commands and the ‘–context’ parameter for dotnet commands.

-c もしくは -context オプションを利用する。
https://docs.microsoft.com/ja-jp/ef/core/managing-schemas/migrations/providers

さらに複数のコンテキストのマイグレーションが同じフォルダーで混ざると気持ち悪いので、-o -output オプションを付けてマイグレーションフォルダーを分けると嬉しい

dotnet ef migrations add InitAppDbContext -c AppDbContext -o Migrations/App
dotnet ef migrations add InitAuthDbContext -c AuthDbContext -o Migrations/Auth

もちろん dotnet ef database update 時にも -c をつけるのをお忘れなく

dotnet ef database update -c AppDbContext
dotnet ef database update -c AuthDbContext
広告
カテゴリー:ASP.NET, MySql タグ: ,

Oracle製のMySQLコネクターは、Entity Framework Core 2.1のマイグレーションに対応していない

データベースのマイグレーションを行うためにデータレイヤーのプロジェクト(Data)でマイグレーションスクリプトの追加コマンドを打ったら

cd Data
migrations add First --startup-project "..\WebSite"

こんなエラーが出ました

An error occurred while accessing the IWebHost on class ‘Program’. Continuing without the application service provider. Error: Object reference not set to an instance of an object.

MSDN の デザイン時 DbContext 作成 を見ると、IDesignTimeDbContextFactory を実装したデザイン時のファクトリを用意するということだったので、こんなクラスを作って WebSite プロジェクトにに追加してみた。

    public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory
    {
        public DefaultDbContext CreateDbContext(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("connectionStrings.json")
                .Build();

            var builder = new DbContextOptionsBuilder()
                .UseMySql(configuration.GetConnectionString("idpdb"));
            return new DefaultDbContext(builder.Options);
        }
    }

今度はこんな感じのエラーが出た

Exception message:
System.MissingMethodException: ‘Method not found: ‘Void Microsoft.EntityFrameworkCore.Storage.Internal.RelationalParameterBuilder..ctor(Microsoft.EntityFrameworkCore.Storage.IRelationalTypeMapper)’.’

Entity Framework Core 2.1 のプレビュー時点でのこんな投稿が、どうも Oracle 版の MySql コネクターは Entity Framework の内部的なクラスを触っているようで、Entity Framework のバージョンアップについてこれていないっぽい。
EF Core 2.1 Preview 1 throws MissingMethodException when using Pomelo.EntityFrameworkCore.MySql

MySqlのフォーラムにもバグとして起票はされているけれど動きはなさそう。
https://bugs.mysql.com/bug.php?id=89855

Oracle は ODP.NET の時も Entity Framework に対する動きがだいぶ遅くてもやもやしたけれど、MySQL も同じっぽいなー。ということで、しばらくは Pomelo 版の MySQL コネクターを使ってみようと思います。
https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql

書き換えは、UseMySQL を UseMySql にするだけなので簡単ですね。

            services.AddDbContext(options =>
                options.UseMySql(
                    Configuration.GetConnectionString("db")
                    , builder => builder.MigrationsAssembly("ata"))
                );
カテゴリー:ASP.NET, MySql

Visual Studio 2017 15.8でdocker-composeを利用する場合は、コンテナオーケストレーターレーターサポートからdocker-compose.ymlを追加する

Visual Studio 2017 バージョン 15.8 で Docker サポートを有効にした ASP.NET Core のアプリケーションを作ったら、docker-compose.yml が自動的に追加されなかったのでメモ

Visual Studio Tools for Docker と ASP.NET Core」の「アプリにコンテナー オーケストレーター サポートを追加する」を参照すると、下記のような記載が追加されていた。

Visual Studio 2017 バージョン 15.8 以降では、指示された場合にのみ、オーケストレーション ソリューションが追加されます。 ソリューション エクスプローラーでプロジェクトを右クリックして、[追加] > [Container Orchestrator Support](コンテナー オーケストレーター サポート) の順に選択します。 Docker Compose と Service Fabric という 2 つの異なる選択肢が提供されています。

MSDNにある通り、プロジェクトのプロパティー > 追加 > コンテナオーケストレーターサポートを選択し、
DockerComposeの追加1

Docker Compose を選択すると、
DockerComposeの追加2

ベースイメージを Windows にするか Linux にするかを尋ねられるのでOSを選択する。
DockerComposeの追加3

ソリューションに docker-compose が追加され、スタートアッププロジェクトに設定される。
DockerComposeの追加6

こんな感じの docker-compose.yml が追加される。

 version: '3.4'

services:
  webapplication1:
    image: ${DOCKER_REGISTRY}webapplication1
    build:
      context: .
      dockerfile: WebApplication1/Dockerfile

複数のプロジェクトに対してコンテナオーケストレーターサポートを追加すると、docker-compose.yml に設定が追加されるので、必要に応じてdepends_onを設定すればよい。

version: '3.4'

services:
  webapplication1:
    image: ${DOCKER_REGISTRY}webapplication1
    build:
      context: .
      dockerfile: WebApplication1/Dockerfile

  webapplication2:
    image: ${DOCKER_REGISTRY}webapplication2
    build:
      context: .
      dockerfile: WebApplication2/Dockerfile
カテゴリー:ASP.NET, Docker タグ: ,

ASP.NET Coreでマイグレーションファイルをマイグレーション専用プロジェクトに配置する。

CodeFirstでプログラムを作っている場合、dotnet コマンドの migrations サブコマンドでマイグレーションスクリプトをプロジェクトに追加しますが、マイグレーションプロジェクトを別のプロジェクトで管理したい場合の方法
https://github.com/bricelam/Sample-SplitMigrations

カテゴリー:ASP.NET, DB, 未分類

Riderでマルチスタートアップ

Visual Studioで複数プロジェクトをいっぺんに実行したりデバックしたりする場合、ソリューションのスタートアッププロジェクト設定でマルチスタートアップから実行するプロジェクトを選択します。

Riderでは複合実行という設定で同じように複数プロジェクトを実行することができます。
マニュアルでは、複合ってなっているんだけれど、IDEではCompoundって名前ですね。
https://pleiades.io/help/rider/Creating_Compound_Run_Debug_Configuration.html

カテゴリー:ASP.NET, Visual Basic

MacでDockerサポートな.net coreをデバックする場合は、/usr/local/share/dotnet/sdk/NuGetFallbackFolderをFileShareに設定する。

Visual Studio 2017で作った、DockerサポートありのASP.NET Coreプロジェクトを、Visual Studio for Macででバックしようとしたら、こんなエラーで怒られた。

/Applications/Visual Studio.app/Contents/Resources/lib/monodevelop/AddIns/docker/MonoDevelop.Docker/MSbuild/Sdks/Microsoft.Docker.Sdk/build/Microsoft.VisualStudio.Docker.Compose.targets(363,5):
error :
ERROR: for dockercompose10154073938731495326_todo_1
Cannot start service todo: b’Mounts denied:
The path /usr/local/share/dotnet/sdk/NuGetFallbackFolder
is not shared from OS X and is not known to Docker.
You can configure shared paths from Docker ->
Preferences… ->
File Sharing.\r\nSee https://docs.docker.com/docker-for-mac/osxfs/#namespaces for more info.

言われた通り、Dockerの設定から、下記のフォルダーをFile Shareに追加したらうまく動いた

/usr/local/share/dotnet/sdk/NuGetFallbackFolder

Riderだとこんなエラーが出て実行できない。
これはWindowsでも同じだから、Rider側の対応が必要そう

Project ‘docker-compose’ load failed: The SDK ‘Microsoft.Docker.Sdk’ specified could not be found.

サポートを見ると現在作業中?

https://rider-support.jetbrains.com/hc/en-us/community/posts/115000634804-Visual-Studio-Tools-for-Docker-Support-needed

リンクにある通り、単にビルドするだけならRiderの拡張機能を使ったり自前でビルドすれば良いんだけれど、デバックまで考えるとVSMacと同等の機能があると嬉しい。

カテゴリー:ASP.NET, DB, Docker, 未分類

StackExchangeでクラスター構成のRedisにTransactionで値を登録する場合はHashTagを使う

こんなコードをクラスター化されたRedisに対して実行すると

こんな例外が発生します。

StackExchange.Redis.RedisCommandException: Multi-key operations must involve a single slot; keys can use ‘hash tags’ to help this, i.e. ‘{/users/12345}/account’ and ‘{/users/12345}/contacts’ will always be in the same slot
場所 StackExchange.Redis.ServerSelectionStrategy.Select(Message message)
場所 StackExchange.Redis.ConnectionMultiplexer.TryPushMessageToBridge[T](Message message, ResultProcessor`1 processor, ResultBox`1 resultBox, ServerEndPoint& server)
場所 StackExchange.Redis.ConnectionMultiplexer.ExecuteAsyncImpl[T](Message message, ResultProcessor`1 processor, Object state, ServerEndPoint server)
場所 StackExchange.Redis.RedisTransaction.ExecuteAsync(CommandFlags flags)
場所 WindowsFormsApplication2.Form1.d__1.MoveNext() 場所 c:\users\sugiyama\documents\visual studio 2015\Projects\WindowsFormsApplication2\WindowsFormsApplication2\Form1.cs:行 36

エラーメッセージにある通り、Multi-keyに対する更新は対象となるデータがすべて同じスロットにある必要があるので、ハッシュタグでくくりましょうねとの事。

ハッシュタグでくくるとなんで同一のスロットに保存されるかはこのドキュメントが詳しい
Premium Azure Redis Cache の Redis クラスタリングの構成方法
https://docs.microsoft.com/ja-jp/azure/redis-cache/cache-how-to-premium-clustering#how-are-keys-distributed-in-a-cluster

という事で、こんなキー構成にするか、トランザクションを諦めるしかないようです。

カテゴリー:ASP.NET タグ: