如何在EF Core中获取数据库表主键列的列表

5

使用EF Core的ASP.NET Core MVC应用程序。在Linq to SQL中,此代码返回数据库表主键列名称列表:

    /// <summary>
    /// Database primary key names
    /// </summary>
    public IList<string> DatabasePrimaryKey(Type dbContextPocoType)
    {
        List<string> pk = new List<string>();

        foreach (PropertyInfo p in dbContextPocoType.GetProperties())
        {
            var ca = p.GetCustomAttributes(typeof(ColumnAttribute), true);

            if (ca.Length == 0) continue;
            var atr = (ColumnAttribute)ca.Single();

            if (!atr.IsPrimaryKey) continue;
            pk.Add(atr.Name);
        }

        return pk;
    }

在 EF Core 中,我尝试过

var entry = ctx.Entry(dbContextPocoType);
var primaryKey = entry.Metadata.FindPrimaryKey();

IList<string>  keys = primaryKey.Properties.Select(x => x.Name).ToList();
return keys;

但是这返回了C#属性名称——如何在EF Core中获取数据库表列名?

更新:使用答案,我创建了这个方法:

    public IList<string> DatabasePrimaryKey<TPoco>()
    {
        var entry = ctx.Entry(typeof(TPoco));
        var primaryKey = entry.Metadata.FindPrimaryKey();
        var entityType = ctx.Model.FindEntityType(typeof(TPoco).Name);
        var schema = entityType.GetSchema();
        var tableName = entityType.GetTableName();
        IList<string> keys = primaryKey.Properties
             .Select(x => x.GetColumnName(StoreObjectIdentifier.Table(tableName, schema)))
             .ToList();
        return keys;
    }

这种方法可以改进吗?

1个回答

12
在 EF Core 3.x 中,您可以尝试使用 IProperty 扩展方法 GetColumnName
var entry = ctx.Entry(dbContextPocoType);
var primaryKey = entry.Metadata.FindPrimaryKey();
var primaryKeyColumns = primaryKey.Properties
                     .Select(property => property.GetColumnName())
                     .ToList()

return primaryKeyColumns;

对于 EF Core 5,您需要使用接受 StoreObjectIdentifier 的重载函数:GetColumnName(IProperty, StoreObjectIdentifier)

更新 EF 5:

public IList<string> DatabasePrimaryKey<TPoco>()
{
    var entityType = ctx.Model.FindEntityType(typeof(TPoco));
    var primaryKey = entityType.FindPrimaryKey();
    var schema = entityType.GetSchema();
    var tableName = entityType.GetTableName();
    var storeObjectIdentifier = StoreObjectIdentifier.Table(tableName, schema);
    IList<string> primaryKeyColumns = primaryKey.Properties
        .Select(x => x.GetColumnName(storeObjectIdentifier))
        .ToList();
    return primaryKeyColumns;
}

谢谢。我更新了答案,并添加了我创建的方法。这个可以改进吗? - Andrus
1
@Andrus,不用谢,很高兴能帮到你。我也更新了我的答案,并提出了一个小的修改建议。虽然我自己没有测试过,但我相信你不需要entry,因为你可以从entityType中找到primaryKey。参考:https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.metadata.ientitytype.findprimarykey?view=efcore-5.0#Microsoft_EntityFrameworkCore_Metadata_IEntityType_FindPrimaryKey - dglozano
2
偶尔我会来到 Stack Overflow 并恰好找到我需要的确切答案。 - Nicholas Franceschina

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接