【问题标题】:ServiceStack OrmLite-Oracle: Can't insert object with sequence attributeServiceStack OrmLite-Oracle:无法插入具有序列属性的对象
【发布时间】:2019-06-17 12:04:38
【问题描述】:

我正在测试 ServiceStack.OrmLite.Oracle (5.5.1),但在创建具有序列属性的模型时无法将数据保存到数据库。尝试使用 API 和生成的 SQL 进行测试,API 不插入数据但生成的 SQL 是正确的。如何解决这个问题?

using System;
using System.Data;
using NUnit.Framework;
using ServiceStack.DataAnnotations;
using ServiceStack.OrmLite;

namespace Tests
{
    public class DatabaseTest
    {
        private readonly IDbConnection _db;

        public DatabaseTest()
        {
            var dbFactory = new OrmLiteConnectionFactory(
                @"Data Source = (DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = ora-test)(PORT = 1521))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = twcms12c))); User Id=scott; Password=Ab123456",
                OracleDialect.Provider);
            _db = dbFactory.OpenDbConnection();
        }

         [Test]
        public void CustomerInsertTest()
        {
            _db.DropAndCreateTable<Person>();
            var customer = new Person {FirstName = "John", LastName = "Smith", Age = 20};

            //Insert by API not work
            _db.Insert(customer);
            var customers = _db.Select<Person>();
            Console.WriteLine("Person count (API) = {0}",customers.Count);

            //Insert by SQL working
            _db.ExecuteSql(_db.ToInsertStatement(customer));
            customers = _db.Select<Person>();
            Console.WriteLine("Person count (SQL) = {0}",customers.Count);
        }
    }

    public class Person
    {
        [AutoIncrement]
        [Sequence("PERSON_SEQ")]
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int? Age { get; set; }
    }
}

输出结果为:

人数 (API) = 0

人数 (SQL) = 1

【问题讨论】:

    标签: servicestack ormlite-servicestack


    【解决方案1】:

    在 ServiceStack.OrmLite.Oracle (5.5.1) 中 GetNextValue (ServiceStack.OrmLite.Oracle.OracleOrmLiteDialectProvider.cs) 方法中存在错误:

            private object GetNextValue(IDbCommand dbCmd, string sequence, object value)
            {
                if (value.ToString() != "0")
                {
                    object retObj;
                    if (long.TryParse(value.ToString(), out var nv))
                    {
                        LastInsertId = nv;
                        retObj = LastInsertId;
                    }
                    else
                    {
                        LastInsertId = 0;
                        retObj = value;
                    }
                    return retObj;
                }
    
                dbCmd.CommandText = $"SELECT {Quote(sequence)}.NEXTVAL FROM dual";
                long result = (long)dbCmd.LongScalar();
                LastInsertId = result;
                return result;
            }
    

    我改成:

            private object GetNextValue(IDbCommand dbCmd, string sequence, object value)
            {
                if (value.ToString() != "0")
                {
                    object retObj;
                    if (long.TryParse(value.ToString(), out var nv))
                    {
                        LastInsertId = nv;
                        retObj = LastInsertId;
                    }
                    else
                    {
                        LastInsertId = 0;
                        retObj = value;
                    }
                    return retObj;
                }
    
                var lastSql = dbCmd.CommandText;
                dbCmd.CommandText = $"SELECT {Quote(sequence)}.NEXTVAL FROM dual";
                long result = (long)dbCmd.LongScalar();
                LastInsertId = result;
                dbCmd.CommandText = lastSql;
                return result;
            }
    

    而且效果很好。 P/s:我创建了一个被 ServiceStack 接受的拉取请求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-21
      • 2016-03-25
      相关资源
      最近更新 更多