Как обойти преобразование параметров к int
От: Аноним  
Дата: 17.08.12 08:29
Оценка:
Столкнулся с интересной проблемой, .net все типы в выражениях ниже int приводит к int,
что очень мешает в некоторых случаях, а именно:

таблица:
[TableName("Table")]
public class TableRow
{
[PrimaryKey]
public long Id;
[MapField("send_status")]
public SendStatusEnum SendStatus;
}
 
public enum SendStatusEnum : byte
{
SendNotAllowed = 1,
SendAllowed =2,
Sent = 3
}


CREATE TABLE [Table](
[id] [bigint] NOT NULL PRIMARY KEY CLUSTERED,
[send_status] [tinyint] NOT NULL,
)


код linq запроса:
_db.Table
.Where(j => j.Id < identity && j.SendStatus == SendStatusEnum.SendNotAllowed)
.Update(row =>
new Table
{
SendStatus = SendStatusEnum.SendAllowed
});



приводит к генерации sql запроса:
UPDATE [j]
SET [send_status] = 2
FROM
[Document].[SELL_SESSION_SEND_ATTRIBUTE] [j]
WHERE [j].[Id] < 123 AND Convert(Int, [j].[send_status]) = 1


он приводит поле в таблице к Int, несмотря на то, что enum имеет тип byte (enum SendStatusEnum : byte)
Convert(Int, [j].[send_status]) = 1

как можно обойти такое поведение?
иначе это может сильно мешать использованию индексов в БД + лишние расходы на конвертацию
Re: Как обойти преобразование параметров к int
От: igr-z  
Дата: 19.08.12 08:21
Оценка:
Оказалось, проблема существует только с типом byte (sbyte — дает тот же результат)
вот пример:


  class Program
    {
    class Program
    {
        static void Main(string[] args)
        {
            using (var conn = new SqlConnection(@"Data Source=.;Database=Test;Integrated Security=SSPI"))
            {
                conn.Open();
                using (var db = new DbManager(conn))
                {
                    var table = db.GetTable<TableTestRow>().
                        Where(row => row.Id == 1 
                            && row.ValueInt == 1 
                            && row.ValueShort == 1 
                            && row.ValueByte == 1
                            && row.ValueEnum == StatusEnum.Status2
                            && row.ValueBit);

                    table.ToList();
                    Console.WriteLine(table.ToString());
                    Console.ReadLine();
                }
            }
        }
    }

    [TableName("TableTest")]
    public class TableTestRow
    {
        public long Id;
        public int ValueInt;
        public short ValueShort;
        public sbyte ValueByte;
        public StatusEnum ValueEnum;
        public bool ValueBit;
   }

    public enum StatusEnum : sbyte
    {
        Status1,
        Status2,
        Status3
    }




CREATE TABLE [dbo].[TableTest](
                [Id] [bigint] NOT NULL PRIMARY KEY CLUSTERED,
                [ValueInt] [int] NOT NULL,
                [ValueShort] [smallint] NOT NULL,
                [ValueByte] [tinyint] NOT NULL,
                [ValueEnum] [tinyint] NOT NULL,
                [ValueBit] [bit] NOT NULL,
)



Дает следующее:

SELECT
        [row1].[Id],
        [row1].[ValueInt],
        [row1].[ValueShort],
        [row1].[ValueByte],
        [row1].[ValueEnum],
        [row1].[ValueBit]
FROM
        [TableTest] [row1]
WHERE
        [row1].[Id] = 1 AND
        [row1].[ValueInt] = 1 AND
        [row1].[ValueShort] = 1 AND
        Convert(Int, [row1].[ValueByte]) = 1 AND
        Convert(Int, [row1].[ValueEnum]) = 1 AND
        [row1].[ValueBit] = 1


конвертируется только byte (sbyte так же)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.