#nhibernate #entity-relationship #nhibernate-criteria
#nhibernate #сущность-отношение #nhibernate-критерии
Вопрос:
У меня есть простые 3 класса POCO:
public class User
{
//PK
public virtual int UserId { get; set; }
//ONE to ONE
public virtual Profil Profil{ get; set; }
//ONE to MANY
public virtual IList<PhotoAlbum> Albums { get; set; }
}
public class Profil
{
//PK
public virtual int ProfilId { get; set; }
public virtual int Age { get; set; }
public virtual int Sex { get; set; }
}
public class PhotoAlbum
{
//PK
public virtual int PhotoAlbumId { get; set; }
public virtual string Name { get; set; }
public virtual int NumberOfPhoto { get; set; }
}
Я создал эти классы сопоставления:
public class UserMap : ClassMap<User>
{
public UserMap()
{
//PK
Id(p => p.UserId)
.GeneratedBy.Identity();
//FK
References(p => p.Profil)
.Column("ProfilId")
.Cascade.All();
//ONE TO MANY
HasMany(p => p.Albums)
.Cascade.All();
Table("Users");
}
}
public class ProfilMap: ClassMap<Profil>
{
public ProfilMap()
{
Id(p => p.ProfilId)
.GeneratedBy.Identity();
Map(p => p.Age)
.Not.Nullable();
Map(p => p.Sex)
Table("Profiles");
}
}
public class PhotoAlbumMap : ClassMap<PhotoAlbum>
{
public PhotoAlbumMap()
{
Id(p => p.PhotoAlbumId)
.GeneratedBy.Identity();
Map(p => p.Name)
.Not.Nullable();
Map(p => p.NumberOfPhoto)
.Not.Nullable();
Table("PhotoAlbums");
}
}
Затем я создал простой класс репозитория NHibernate с помощью этого метода:
public IList<T> GetItemsByCriterions(params ICriterion[] criterions)
{
ICriteria criteria = AddCriterions(_session.CreateCriteria(typeof(T)),
criterions);
IList<T> result = criteria.List<T>();
return result ?? new List<T>(0);
}
Для теста я создал репозиторий для некоторого объекта, например пользователя:
_userRepo = new NHibRepository<User>(NHibeHelper.OpenSession());
и я хотел бы иметь возможность сделать запрос в этом стиле:
var users = _userRepo.GetItemsByCriterions(new ICriterion[]
{
Restrictions.Gt("Profile.Age",10)
});
эта попытка завершилась ошибкой:
не удалось разрешить свойство: Профиль: Repository.User
Пользователь имеет свойство Profile тип профиля, и это свойство имеет свойства ProfileID, Возраст и пол.
** ОТРЕДАКТИРОВАНО #1:**
@ Я попробовал это:
var users = _userRepo.GetItemsByCriterions(new ICriterion[]
{
Restrictions.Where<User>(u=>u.Profil.Sex==0)
});
закончено с ошибкой:
не удалось разрешить свойство: Профиль.Пол: Репозиторий.Пользователь
#2 ОТРЕДАКТИРОВАНО
Я попытался воспользоваться советом Натана:
var result = _userRepo.Session.CreateCriteria<User>()
.CreateAlias("Profile", "profile", JoinType.InnerJoin)
.Add(Restrictions.Eq("profile.Sex", 0));
IList<User> users=null;
if (result != null)
users = result.List<User>();
Если я попытаюсь преобразовать результат в список, я снова получу эту ошибку: не удалось разрешить свойство: Profile of: Repository.User
Ответ №1:
Глядя на ваш пример, пользователь имеет свойство Profil, а не свойство Profile.
Если предполагается, что это Profil, я бы изменил Restrictions.Gt(Profile.Age,10)
, чтобы Restrictions.Gt(Profil.Age,10)
в противном случае изменить имя свойства и сопоставления в соответствии с запросом.
Редактировать:
Вы пытаетесь запросить пользовательский объект. вам необходимо включить createAlias, чтобы nhibernate знал, что вы хотите связать с другим объектом.
Попробуйте это.
var users = session.CreateCriteria<User>()
.CreateAlias("Profile", "profile", JoinType.InnerJoin)
.Add(Restrictions.Eq("profile.Age", 10));
Комментарии:
1. Спасибо за совет, но когда я попытался преобразовать пользователей в список <User>, я снова получил то же исключение: не удалось разрешить свойство: Profile of: Repository.User
2. Я создал репозиторий bitbucket bitbucket.org/gonefishern/so_7952683 с очень простым тестовым приложением, которое показывает, что оно работает. если вы загружаете исходный код, вам нужно будет установить пакеты fluentnhibernate и SqlServerCompact