Использует ли Entity Framework / LINQ to SQL Binding Data отражение? - PullRequest
8 голосов
/ 20 апреля 2009

Простите, если об этом уже спрашивали; Я выполнил поиск, но не смог найти ничего, что конкретно ответило бы на этот вопрос, но я был бы рад, если бы меня направили.

Я взгляну на Entity Framework и LINQ to SQL, и хотя мне нравятся системы (и, конечно, интеграция LINQ), я немного скептически отношусь к аспекту привязки данных. Я взял результаты запросов и проверил их, и они, кажется, не реализуют стандартные интерфейсы привязки списков .NET (IBindingList, и что более важно ITypedList), что наводит меня на мысль, что они связываются с сеткой ( или что-нибудь еще) собирается использовать отражение, чтобы получить / установить свойства моей сущности. Это кажется сравнительно дорогой операцией, особенно когда весь код генерируется в любом случае и может реализовывать интерфейсы.

У кого-нибудь есть понимание этого? Используется ли отражение для получения / установки значения свойств? Если да, оказывает ли это заметное влияние на производительность, и есть ли у кого-нибудь идеи, почему они пошли по этому пути?

Редактировать

На самом деле я концентрируюсь на том, реализован ли ITypedList где-нибудь по пути, поскольку именно он обладает способностью предоставить явный механизм для определения и взаимодействия со свойствами без обращения к отражению. Хотя у меня не было проекта LINQ to SQL, я проверил простой результат запроса сущности Entity Framework, и он, по-видимому, не реализовал ITypedList. Кто-нибудь знает, если я просто смотрю на что-то неправильно, или если нет, то почему это так?

Редактировать 2

Приняв ответ Марка, я подумал, что для других было бы полезно, если бы я опубликовал какой-то простой код, который использовал для бесшовной реализации его решения. Я поместил следующее в статический конструктор для моего класса:

public static ContextName()
{
    foreach(Type type in System.Reflection.Assembly.GetExecutingAssembly()
        .GetTypes())
    {
        if (type.GetCustomAttributes(typeof(System.Data.Linq.Mapping
            .TableAttribute), true) != null)
        {
            System.ComponentModel.TypeDescriptor.AddProvider(
                new Hyper.ComponentModel.HyperTypeDescriptionProvider(
                    System.ComponentModel.TypeDescriptor.GetProvider(
                        type)), 
                type);
        }
    }
}

Хотя это и для LINQ to SQL, я уверен, что для Entity Framework может быть написана эквивалентная версия. Это отсканирует сборку для любых типов с атрибутом Table и добавит настраиваемый поставщик для каждого из них.

Ответы [ 3 ]

3 голосов
/ 20 апреля 2009

API-интерфейс Expression, который лежит в основе LINQ и т. Д., Основан на отражении (MemberInfo), а не на модели компонента (PropertyDescriptor и т. Д.), Поэтому для ITypedList нет огромных требований. Вместо этого содержимое выводится из T в IQueryable<T>, IEnumerable<T> и IList<T> и т. Д.

Самое близкое, что вы можете получить, это IListSource, но это все равно будет просто обертка вокруг правильного типизированного списка.

Если производительность привязки во время выполнения (до PropertyDescriptor) является ключевой, вы можете посмотреть на HyperDescriptor - который использует Reflection.Emit и TypeDescriptionProvider для переноса модели компонента.

Ре "почему" и т. Д .; обратите внимание, что почти во всех случаях с LINQ-to-SQL и EF Expression (или часть «создания и установки членов») будет скомпилирована делегату перед его вызовом - поэтому во время выполнения нет огромного отражения Стоимость. И точно так же, с LINQ-to-Objects все уже скомпилировано (компилятором C #).

1 голос
/ 20 апреля 2009

Из моего опыта работы с LINQ to SQL я по нескольким причинам пришел к выводу, что LINQ использует отражение для установки и получения значений полей в экземплярах класса сущностей. Я не знаю, смогу ли я вспомнить все причины, но вот что я могу вам сказать.

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

Я думаю, что это делает это для обеспечения простоты - вы можете полагаться на значения в полях в классе сущностей, непосредственно отражающих значения столбцов базы данных, и нет особых накладных расходов при извлечении объекта из базы данных (заполнении вновь созданного сущность, соответствующая значениям, полученным из базы данных, не должна маршрутизироваться через процедуры свойств). Например, одна вещь, которую я сделал для представления перечисляемых значений, извлеченных из базы данных, - это сделать некоторые из сгенерированных LINQ свойств частными и обернуть их в закодированное вручную свойство в частичном классе, который читает и записывает свойство LINQ.

0 голосов
/ 20 апреля 2009

Если посмотреть на то, что MSDN говорит о связывании данных LINQ to SQL, он, похоже, использует IListSource или IBindingList.

Кстати, LINQ использует Деревья выражений , и это не столько отражение, сколько метапрограммирование. Производительность должна быть намного лучше, чем отражение. Чарли Калверт рассказывает об этом немного в этой статье .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...