5

我正在使用 Dapper Extensions,但我的数据库中有多个模式名称。

我在下面的链接中找到了答案,但它假设我只有一个模式名称,这不是我的情况。 Dapper 扩展更改架构

在运行时更改模式名称的正确方法是什么?

4

1 回答 1

0

可能你不会再使用它了,但也许有更多的人在那里试图弄清楚。

我一直在检查 dapper 在运行GetAll<>Insert<>.

它能做什么:

var type = typeof(T);
var cacheType = typeof(List<T>);

if (!GetQueries.TryGetValue(cacheType.TypeHandle, out string sql))
{
    GetSingleKey<T>(nameof(GetAll));
    var name = GetTableName(type); <--- key thing

    sql = "select * from " + name;
    GetQueries[cacheType.TypeHandle] = sql;
}

所以我检查了GetTableName在做什么:

private static string GetTableName(Type type)
{
    if (TypeTableName.TryGetValue(type.TypeHandle, out string name)) return name;

    if (TableNameMapper != null)
    {
        name = TableNameMapper(type); <-- key thing
    }
    else
    {
        //NOTE: This as dynamic trick should be able to handle both our own Table-attribute as well as the one in EntityFramework 
        var tableAttr = type
#if NETSTANDARD1_3
            .GetTypeInfo()
#endif
            .GetCustomAttributes(false).SingleOrDefault(attr => attr.GetType().Name == "TableAttribute") as dynamic;
        if (tableAttr != null)
        {
            name = tableAttr.Name;
        }
        else
        {
            name = type.Name + "s";
            if (type.IsInterface() && name.StartsWith("I"))
                name = name.Substring(1);
        }
    }

    TypeTableName[type.TypeHandle] = name;
    return name;
}

解决方案:

所以我想我可以用这样的代码实现我自己的表名映射器:

SqlMapperExtensions.TableNameMapper = DapperMapper.TableNameMapper();

public static SqlMapperExtensions.TableNameMapperDelegate TableNameMapper()
{
    return (type) =>
    {
        var has = Attribute.GetCustomAttribute(type, typeof(CastleTableAttribute));
        if (has != null)
        {
            return $"{ConfigurationProvider.Schema}.{type.Name}";
        }
        else
        {
            return type.Name;
        }
    };
}

使用该名称映射器,您只需要用它标记您的表。

[CastleTable]
class CubeTimestamps
{
    [ExplicitKey]
    public int cube_id { get; set; }
    public DateTime cube_timestamp { get; set; }
}

您也可以实现您的名称映射器以使用 [TableName] 属性。因为我的简单实现隐藏了这个特性。

享受 :)

于 2018-04-23T09:00:23.903 回答