Отношения один-к-одному карты не позволяют вставлять - PullRequest
2 голосов
/ 11 января 2011

Я пытаюсь настроить однозначное сопоставление моих пользователей с таблицей UserDetails.Допустим, в моей базе данных есть следующие таблицы:

Users:

- UserID (PK, Identity)
- UserName
- Password

UsersDetails:

- UserID (PK, FK)
- FirstName
- LastName

Я создал следующие классы poco:

public class User {
    public virtual int UserID { get; set; }
    public virtual string UserName { get; set; }
    public virtual string Password { get; set; }
    public virtual UserDetails Details { get; set; }
}

public class UserDetails {
    public virtual int UserID { get; set; }
    public virtual User User { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }

    public UserDetails() {
    }

    public UserDetails(User user) {
        User = user;
    }
}

, которые свободно отображаются (обратите внимание, что отображение xml очень похоже иесли все, что вы знаете, это отображение xml, то я все равно буду признателен вам за указание):

public class UserMap : ClassMap<User> {
    public UserMap() {
        Table("Users");
        Id(x => x.UserID);
        Map(x => x.UserName);
        Map(x => x.Password);
        HasOne(x => x.Details)
            .Constrained()
            .Cascade.All();
    }
}

public class UserDetailsMap : ClassMap<UserDetails> {
    public UserDetailsMap() {
        Table("UsersDetails");
        Id(x => x.UserID)
            .GeneratedBy.Foreign("User");
        HasOne(x => x.User)
            .Constrained();
        Map(x => x.FirstName);
        Map(x => x.LastName);
    }
}

Все отображается правильно, но если я скажу:

var user = new User() { UserName = "Test", Password = "Test" };
user.Details = new UserDetails(user) { FirstName = "Test", LastName = "Test" };
session.Save(user);

Я получу ошибку:

"NHibernate.Id.IdentifierGenerationException: пустой идентификатор, сгенерированный для: UserDetails."

Я был бы очень признателен, если бы кто-то мог показать мне, что я сделал неправильно.Спасибо

Редактировать: Предоставлено предложение Джейми Иде.Я изменил свое сопоставление пользователя на:

public class UserMap : ClassMap<User> {
    public UserMap() {
        Table("Users");
        Id(x => x.UserID);
        Map(x => x.UserName);
        Map(x => x.Password);
        References(x => x.Details, "UserID")
            .Class<UserDetails>()
            .Unique();
    }
}

Но теперь, когда я вставляю пользователя, я получаю сообщение об ошибке:

"System.ArgumentOutOfRangeException: индекс был вне диапазона. Должен быть неотрицательно и меньше размера коллекции. "

Если я добавлю Cascade.All () в свою ссылку, я получу исходную ошибку, которую я получаю о сгенерированном нулевом идентификаторе.

Ответы [ 5 ]

2 голосов
/ 12 января 2011

Я думаю, Constrained следует указывать только в UserDetailsMap, а не в UserMap.Попробуйте:

public class UserMap : ClassMap<User> {
    public UserMap() {
        Table("Users");
        Id(x => x.UserID);
        Map(x => x.UserName);
        Map(x => x.Password);
        HasOne(x => x.Details)
            .Cascade.All();
    }
}

РЕДАКТИРОВАТЬ:

См. это и это .Похоже, что вы должны отобразить отношения как многие-к-одному со стороны пользователя и один-к-одному со стороны UserDetails, чтобы ленивая загрузка работала один-к-одному.Я не знаю, отличается ли это в NH3.

0 голосов
/ 23 мая 2011

После дальнейших исследований выясняется, что это не будет работать в версии 2.0. Сейчас я в состоянии перейти на версию 3.0, где я считаю, что это теперь возможно.

0 голосов
/ 14 февраля 2011

http://gorbach.wordpress.com/2010/09/24/fluent-onetoone/

HasOne(x => x.Details).Cascade.All().ForeignKey("UserDetails");
HasOne(x => x.User).Constrained();
var user = new User() { UserName = "Test", Password = "Test" };
user.Details = new UserDetails(user) { FirstName = "Test", LastName = "Test" };
user.Details.User = user;
session.Save(user);
0 голосов
/ 12 января 2011

Я думаю, что вам нужно иметь отображение идентификатора внешнего ключа в вашем отображении пользователя вместо UserDetails и собственного в UserDetails. Однако мне не удалось найти ссылку на него.

0 голосов
/ 11 января 2011

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

Id(x=>x.UserId);

Я не знаю идеи использования Foreign и как она вписывается в вещи здесь ... не могли бы вы проиллюстрировать логику этого?

...