#c# #fluent-nhibernate
#c# #fluent-nhibernate
Вопрос:
Чтобы централизовать часть моей логики для каждого сопоставления классов FluentNHibernate (в частности, для сопоставления свойств аудита и фактического основного идентификатора), у меня есть базовая карта классов под названием AuditedEntityClassMap, которая выглядит примерно следующим образом:
public class AuditedEntityClassMap<TEntity, T> : ClassMap<TEntity> where TEntity : AuditedPersistentObject<T>
{
public AuditedEntityClassMap()
{
Cache.ReadWrite();
DynamicUpdate();
ApplyId();
this.ChangeAuditInfo();
}
protected virtual void ApplyId()
{
if (typeof(T) == typeof(int))
map.Id(x => x.Id).GeneratedBy.HiLo(HiLoConstants.NHibernateHiLoTable, HiLoConstants.NHibernateHiLoColumn, HiLoConstants.NHibernateHiLoMaxLo);
else if (typeof(T) == typeof(Guid))
map.Id(x => x.Id).GeneratedBy.GuidComb();
else
throw new InvalidIdTypeInClassMappingException("Invalid type set in class mapping: " typeof(T));
}
}
Мой вопрос заключается в том, что проверка типа универсального, чтобы определить тип отображения генератора NHibernate, которое следует использовать для него, пахнет, и мне интересно, есть ли лучший способ справиться с этим.
- Универсальный тип для идентификаторов объектов моего домена используется повсеместно и отлично работает везде (и он широко используется).
- Я бы предпочел не определять отображение идентификаторов в ClassMap каждого объекта, если я могу этого избежать. Если это единственный способ сделать это, я смирюсь с этим.
Мысли и предложения?
Ответ №1:
Я не смог скомпилировать ваш код, но я удивлен, что это работает.
Не будет ли T классом данных вместо идентификатора.
Другой способ, который я могу предложить, — это отражение, но я не могу представить, что это намного лучший способ.
Вы могли бы получить свойства T с помощью отражения и выполнить поиск свойства с именем Id или id-код. А затем получает тип этого свойства. Но я не знаю, как бы вы назвали Map в этом контексте.
var pp = typeof(T).GetProperties().Where(p => p.Name == "Id").FirstOrDefault();
if (pp != null)
{
if (pp.PropertyType.Name == "Int64" || pp.PropertyType.Name == "Int32")
{
Map();
}
}
Комментарии:
1. Спасибо за очень быстрый ответ. Я удалил это вскоре после публикации, но, думаю, после того, как вы увидели это и начали отвечать. Да, синтаксис был неправильным и с тех пор был обновлен.
2. Добавление отражения туда было бы еще более неприятным на мой взгляд. Запах, на мой взгляд, связан с тем, что дженерик уже давно не является универсальным в цепочке, что сводит на нет смысл того, чтобы он был универсальным в первую очередь (помимо того факта, что он бесценен везде в этой цепочке).
3. На предыдущих итерациях я просто выполнял AuditedEntityClassMapOfGuid, AuditedEntityClassMapOfInt и т.д. И просто устанавливал класс-наследник как применимый. Но это мне понравилось еще меньше.
4. «обработка универсального как более не универсального на этом этапе цепочки, что сводит на нет смысл того, чтобы оно было универсальным в первую очередь» Я попытался прочитать это, но моя голова взорвалась 🙂 Вероятно, лучше всего, если вы найдете другой подход, это может только усугубить ситуацию
5. Спасибо yavosh. Если другого способа нет, то я думаю, что оставлю все как есть. Если бы это имело дело с бесконечным числом типов, у меня была бы проблема. Но как бы то ни было, два типа, возможно, три, все это хорошо.
Ответ №2:
Похоже, нет ничего лучше того, что у меня есть сейчас.