ServiceStack OrmLite-Oracle: невозможно вставить объект с атрибутом последовательности - PullRequest
1 голос
/ 31 мая 2019

Я тестирую ServiceStack.OrmLite.Oracle (5.5.1), но не могу сохранить данные в базу данных при создании модели с атрибутом Sequence. Попробуйте протестировать с помощью 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

1 Ответ

2 голосов
/ 17 июня 2019

В 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.

...