Столкнулся с интересной проблемой, .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
как можно обойти такое поведение?
иначе это может сильно мешать использованию индексов в БД + лишние расходы на конвертацию
Оказалось, проблема существует только с типом 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 так же)