Oracle与EntityFramework(EF)的一些事情

概要

Oracle 和EF 一起用的时候总会有各种问题,这里总结一下解决办法。

模式 Schema

用过Oracle的人应该知道,其实Oracle的用户名一般就是它的模式名称,如果你在用database first 模式构建edmx文件,那么恭喜你,一旦你换了用户名就会出错!

所以尽量避免用edmx来配合使用,推荐用model first模式,就是改了数据结构,自己把对应的模型也改了。

在这个时候,还是避免不了模式问题,这里提供一个办法:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    //模式调整
    modelBuilder.HasDefaultSchema(GetSchemaByConName(ConnectionName));
}

这样就根据数据库连接字符串来初始化模式,避免被模式坑了。

表和列名大写

Oracle 的表名和列名默认都是大写的,区分大小写,当初遇到的时候可是把我坑的好惨。。。

后面找到方法将 所有列名(属性名),表名全部转换为大写,添加统一的映射。

        /// <summary>
        /// create
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //表名调整
            modelBuilder.Types().Configure(x => x.ToTable(EFStartup.SetTableName(x.ClrType.Name)));

            if (IsOracleDb)
            {
                //模式调整
                modelBuilder.HasDefaultSchema(EFStartup.GetSchemaByConName(ConnectionName));
                //列名调整
                modelBuilder.Properties().Configure(c => c.HasColumnName(c.ClrPropertyInfo.Name.ToUpper()));
            }
        }

    /// <summary>
    /// EF预热
    /// </summary>
    internal static class EFStartup
    {
        /// <summary>
        /// 通过数据库连接名称获取模式名称(Oracle用)
        /// </summary>
        /// <param name="conName"></param>
        /// <returns></returns>
        internal static string GetSchemaByConName(string conName)
        {
            if (string.IsNullOrEmpty(conName)) throw new ArgumentNullException(nameof(conName));
            var c = ConfigurationManager.ConnectionStrings[conName];
            if (c == null)
                throw new InvalidOperationException("Db Connection Not Found :" + conName);
            if (string.IsNullOrEmpty(c.ConnectionString))
                throw new Exception($"ConnectionString {conName} is empty!");
            //获取User Id
            var sp = c.ConnectionString.Split(';');
            var u = sp.Where(x => !string.IsNullOrEmpty(x) && x.Contains("=")).FirstOrDefault(y => y.Trim().ToLower().StartsWith("user"));
            if (u == null)
                throw new Exception($"ConnectionString {conName} is invalid !");
            sp = u.Split('=');
            return sp[1].Trim().ToUpper();
        }
        
        /// <summary>
        /// 调整表名称
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public static string SetTableName(string tableName)
        {
            var n2 = tableName.Replace("Ms", "Mon_");
            if (n2.EndsWith("History"))
                n2 = n2.Replace("History", "His");

            n2 = n2.ToUpper();
            return n2;
        }        
    }

通过这个设定,可以把所有实体的名字变成大写,并且可以根据需要增加前缀等,另外把实体模型的所有字段都改成大写,这样就不用纠结那些破事了。

转载于:https://www.cnblogs.com/fallstar/p/8868062.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值