Entity FrameworkコアのDbContextから列名と対応するデータベース型を取得する方法

.net-core c# entity-framework entity-framework-core

質問

このテーブルがあるとします:

ここに画像の説明を入力

Entity Framework CoreのDbContextから列名とデータベースのデータ型を取得するにはどうすればよいですか?

ヒント

  1. 名前がclg#の列がEF Core Scaffoldツールによってclg1に変換されたので、現在のEF名ではなく実際の列名が必要です

  2. 私はもちろん、クロスプラットフォームでなければならないclrTypeではなく、データベースの種類が必要です。たぶん私はデータベースを変更して、メソッドも機能するようにします。

望ましい結果:

    <D.clg#, int>
    <D.clgname, nvarchar(50)>
    <D.city, nvarchar(50)>
    <D.pname, nvarchar(50)>

誰でもソリューションを提供できますか?

受け入れられた回答

アップデート: EF Core 2.0以降、状況は変わりました。元の回答はもう適用されません。現在、EFコアはデータベース型ごとに別々のモデルを構築しているので、コードはずっと簡単で、 Relational()拡張を直接使用します。

var entityType = dbContext.Model.FindEntityType(clrEntityType);

// Table info 
var tableName = entityType.Relational().TableName;
var tableSchema = entityType.Relational().Schema;

// Column info 
foreach (var property in entityType.GetProperties())
{
    var columnName = property.Relational().ColumnName;
    var columnType = property.Relational().ColumnType;
};

元の回答(EF Core 1.x):

関連するメタデータへのアクセスを得ることがEFに比べEFコアにはるかに簡単です-あなたがから開始DbContext.Model取得するプロパティIModel使用し、 GetEntityTypesまたはFindEntityType取得するにはIEntityType 、その後、 GetPropertiesFindProperty取得するIPropertyなど

しかし、問題は、EFコアで異なるターゲットデータベースと異なる設定を使用できることです。コンテキストで使用されている現在のデータベースに対応する属性を取得するには、 IRelationalDatabaseProviderServicesアクセスし、 AnnotationProviderおよびTypeMapperプロパティを使用して必要な情報を取得する必要があります。

次に例を示します。

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Storage;

public class DbColumnInfo
{
    public string Name;
    public string Type;
}

public static class RelationalDbHelpers
{
    public static IEnumerable<DbColumnInfo> GetDbColums(this DbContext dbContext, Type clrEntityType)
    {
        var dbServices = dbContext.GetService<IDbContextServices>();
        var relationalDbServices = dbServices.DatabaseProviderServices as IRelationalDatabaseProviderServices;
        var annotationProvider = relationalDbServices.AnnotationProvider;
        var typeMapper = relationalDbServices.TypeMapper;

        var entityType = dbContext.Model.FindEntityType(clrEntityType);

        // Not needed here, just an example 
        var tableMap = annotationProvider.For(entityType);
        var tableName = tableMap.TableName;
        var tableSchema = tableMap.Schema;

        return from property in entityType.GetProperties()
               let columnMap = annotationProvider.For(property)
               let columnTypeMap = typeMapper.FindMapping(property)
               select new DbColumnInfo
               {
                   Name = columnMap.ColumnName,
                   Type = columnTypeMap.StoreType
               };
    }
}


Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ