Можно ли использовать отражение, чтобы получить имена и значения свойств в базовом классе? - PullRequest
1 голос
/ 10 сентября 2009

Я использую следующий код для сохранения объекта и всех его свойств в БД. Это избавляет меня от необходимости создавать метод сохранения в каждом бизнес-объекте. Код в моем базовом классе:

    public void Save()
    {
        List<SqlParameter> Params = new List<SqlParameter>();
        foreach (PropertyInfo Property in this.GetType().GetProperties())
        {
            if (Property.CanRead)                
                Params.Add(new SqlParameter(Property.Name,Property.GetValue(this,null)));                
        }
        Execute<int>(SaveProcedure, Params.ToArray());        
    }

Это хорошая практика, или мне лучше не использовать отражение и создавать метод сохранения в каждом создаваемом мной объекте?

Любые другие идеи или предложения приветствуются, спасибо!

Ответы [ 5 ]

7 голосов
/ 10 сентября 2009

Похоже, вы создаете свой собственный базовый ORM .Рассматривали ли вы использование какого-либо из полнофункциональных сопоставителей, специально написанных для .NET Framework, для выполнения этой задачи, например LinqToSql или NHibernate ?

1 голос
/ 10 сентября 2009

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

Помимо затрат на отражение, это также, как правило, плохая практика с точки зрения намерения. Вы сохраняете ВСЕ свойства ... но что происходит, когда кто-то создает производный тип, свойства которого не отображаются в столбце таблицы базы данных? Вы должны сделать свой метод сохранения виртуальным или абстрактным, а также реализовать / расширить метод по мере необходимости для каждой сущности.

В заключение: обработка сбережений непосредственно на объекте, подобном этому, - настоящий кошмар обслуживания, ожидающий своего появления. Вы спрашиваете об АД много проблем, поскольку вы объединяете проблемы и обязанности в одном классе. Вам было бы гораздо лучше сделать ваши объекты / бизнес-объекты POCO (обычные старые объекты clr) и написать явные средства отображения данных. Это разделит ваши проблемы и уменьшит обязанности каждого класса до как можно меньшего числа. Богатые, самосохраняющиеся (и загружаемые) сущности удобны, но в основном это мечта. На практике они, как правило, не стоят того небольшого преимущества, которое они предлагают, в свете гораздо больших трудностей в обслуживании, которые у вас будут.

Я рекомендую изучить мапперы OR (LINQ to SQL, nHibernate, Entity Framework v4 и т. Д.) ИЛИ мапперы автоматически генерируют SQL для вас, когда вам нужно загрузить, сохранить или удалить сущности. Они могут исключить значительное количество дополнительного кодирования, необходимого, когда вы не используете OR, и поддерживать гораздо более адаптируемую кодовую базу.

0 голосов
/ 10 сентября 2009

С точки зрения дизайна, я думаю, что более гибко иметь отдельное сохранение для каждого класса. Это позволит выбрать те же свойства, что и вы, и разрешить необходимую предварительную обработку перед сохранением в БД (т. Е. Сам сложный объект сохранить нельзя.

0 голосов
/ 10 сентября 2009

Отражение действительно предназначено только для анализа программы. Использование его имеет довольно серьезные побочные эффекты для производительности и доказуемости вашей программы. Это не значит, что не бывает случаев, когда рефлексия уместна в производственном приложении, но я не думаю, что это один из таких случаев. Для хранения в базе данных я рекомендую поискать сериализацию.

0 голосов
/ 10 сентября 2009

Как человек, чья работа сильно зависит от размышлений, я не думаю, что это неуместно. ОДНАКО, вы должны внимательно рассмотреть его компромисс. Использование Reflection отключит вас от проверки времени компиляции, а это означает, что не будет раннего обнаружения ошибок. Поэтому, если вы действительно думаете, что рефлексия помогает вам лучше управлять кодом, и вы не возражаете против его производительности, использование рефлексии не должно быть проблемой.

Еще одно замечание: каждый раз, когда вы используете рефлексию, убедитесь, что вы создаете достаточно тестов, чтобы помочь вам обнаружить проблему на раннем этапе.

Просто хоть.

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