EF 4.1 компактный байт SQL

#c# #.net #entity-framework #entity-framework-4 #sql-server-ce-4

#c# #.net #entity-framework #entity-framework-4 #sql-server-ce-4

Вопрос:

У меня есть несколько узких мест в производительности в моих запросах. Что происходит, так это то, что всякий раз, когда я ввожу свойство в виде байта в моей сущности, EF 4.1 преобразует его в int перед началом работы с ним. Приведенный код объяснит:

 var segmentQuery = workUnit.SegmentRepository.GetQuery()
                                             .Where(x => x.FileId == file.Id)
                                             .Where(x => x.StateValue == (byte)SegmentState.Unhandeled)
                                             .OrderBy(x => x.Index);
  

Прекрасно переводится на:

 SELECT 
....
FROM ( SELECT 
    [Extent1].[Id] AS [Id], 
    ...
    [Extent1].[StateValue] AS [StateValue]
    FROM [Segments] AS [Extent1]
    WHERE ([Extent1].[FileId] = @p__linq__0) AND (0 = [Extent1].[StateValue])
)  AS [Project1]
ORDER BY [Project1].[Index] ASC
  

Однако в приведенном выше случае: значение состояния на самом деле является целым числом, что слишком много для моих требований (4 разных состояния), но при изменении его на байт я получаю:

 SELECT ...
FROM ( SELECT 
    [Extent1].[Id] AS [Id], 
      ...
    [Extent1].[StateValue] AS [StateValue]
    FROM [Segments] AS [Extent1]
    WHERE ([Extent1].[FileId] = @p__linq__0) AND (0 = ( CAST( [Extent1].[StateValue] AS int)))
)  AS [Project1]
ORDER BY [Project1].[Index] ASC
  

Поскольку в один прекрасный день эта таблица может содержать более 100 000 строк, ее пространство эффективно (хотя, к счастью, не обязательно) для того, чтобы ее поле состояния занимало всего 1 байт, однако изменение на байты убивает мои запросы.

Я сделал что-то не так? Могу ли я что-нибудь сделать? известна ли эта «проблема»?

Спасибо!

** ОБНОВИТЬ **

 [Flags]
public enum SegmentState : byte
{
    Unhandeled,
    Downloaded,
    Invalid,
    Assembled
}
  

и в моей сущности:

 /// <summary>
/// Dont use this, use SegmentState instead
/// </summary>
[Required]
public byte StateValue
{
    get { return _stateValue; }
    set { _stateValue = value; }
}

public SegmentState State
{
    get { return (SegmentState)StateValue; }
    set 
    {
        if (State != value)
        {
            StateValue = (byte)value;
            RaisePropertyChanged(StatePropertyName);
        }
    }
}
  

Комментарии:

1. можете ли вы опубликовать типы StateValue and SegmentState`? если вы обрабатываете большие объемы данных, то я не думаю, что SQL CE сможет с ними справиться

Ответ №1:

Серьезно, не используйте EF — это будет самой большой болью в вашей жизни. Взгляните на MASSIVE и Dynamics в C # — это откроет вам глаза на жизнь 😉

Комментарии:

1. Ага, ответ, который мне не нравится слышать 😉 я просто заменил свой обычный старый уровень Sql DB на аккуратный уровень EF 4.1. Он прекрасен во многих отношениях, хотя есть некоторые проблемы (подобные этой). К счастью, я всегда могу вернуться к простым старым SQL-запросам в EF (но скорее нет).

2. Massive тоже хорош, но у него есть свои недостатки, я не люблю использовать dynamics, когда в этом действительно нет необходимости. Я выбрал . NET и C # по какой-то причине, и я хочу придерживаться этого

3. Пока вы не стремитесь к производительности, EF может быть вариантом 😉

4. Мы не должны начинать дискуссию здесь, но …. вы частично неправы. EF оптимизирован не настолько хорошо, чтобы соответствовать высокой производительности, но работает довольно хорошо (особенно с внедренным интеллектуальным планировщиком запросов SQL CE). Я видел массивные инструкции linq, превращенные в высокооптимизированные SQL-запросы, которые я бы не написал более оптимизированными. EF — это определенно вариант. (я знаю о проблемах с производительностью на стороне клиента, но даже с этим можно справиться, хотя я согласен, что это все еще медленнее, чем массово, но это лишь крошечная часть)

5. Посмотрите на dapper и увидите, как EF истекает кровью. code.google.com/p/dapper-dot-net