Entity DB Добавление нового пользователя и других связанных данных в DB - PullRequest
1 голос
/ 27 августа 2010

Эй.Вопрос Nooby, но новый с Entity.

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

У меня естьпопытался сделать это в одну поездку.Нужно ли сначала добавлять пользователя в базу данных, а затем возвращаться, устанавливать идентификаторы пользователей для других объектов и добавлять их.Вот модель сущности и код для разработки:

alt text

            using (var context = new ServicesEntities())
        {
            newUser = new UsersTable();

            newUser.Address = user.UserDetails.Address;
            newUser.City = user.UserDetails.City;
            newUser.Country = user.UserDetails.Country;
            newUser.Email = user.Email.EmailString;
            newUser.FirstName = user.UserDetails.FirstName;
            newUser.LastName = user.UserDetails.LastName;
            newUser.State = user.UserDetails.State;
            newUser.Zip = user.UserDetails.Zip;

            context.UsersTables.AddObject(newUser);
            context.SaveChanges();
        }

        using (var context = new ServicesEntities())
        {                               
            var referralDetails = new UserReferrals();
            referralDetails.CreatedThruServiceId = 1; // todo don't make this an absolute 1
            referralDetails.ReferralEmail = user.ReferralDetails.ReferralEmail;
            referralDetails.TwoPlusTwoHandle = user.ReferralDetails.TwoPlusTwoHandle;
            referralDetails.UserId = newUser.UserId;               

            context.UserReferrals.AddObject(referralDetails);

            context.SaveChanges();           // THIS WORKS FINE!    
        }

        using (var context = new ServicesEntities())
        {
            var credentials = new UserCredentials();
            credentials.CreatedOn = DateTime.Now;
            credentials.EmailValidated = false;
            //credentials.EmailValidatedOn = null;
            credentials.FailedLoginAttempts = 0;
            credentials.IsLockedOut = false;
            //credentials.LastValidLogin = null;
            credentials.Password = user.Password.PasswordString;
            credentials.PermissionId = 1; // todo don't make this an absolute 1 = user
            credentials.SuccessfulLoginAttempts = 0;
            credentials.UserId = newUser.UserId;        ;

            context.UserCredentials.AddObject(credentials);

            context.SaveChanges(); // THIS ONE CRAPS OUT!
        }

Когда я запускаю это, я получаю следующее исключение при запуске SaveChanges ():

{"Зависимое свойство в ReferentialConstraint сопоставлено с столбцом, сгенерированным хранилищем. Столбец: 'UserId'."}

Примечание: обновлено с помощью немного другого кода на основена примере из книги.

Примечание 2: Я сузил проблему, связанную с добавлением учетных данных.

Примечание 3:Исправлено, я случайно установил AUTO-INCREMENT в свой идентификатор пользователя UserCredentials.Если кто-то здесь, это рабочий код:

public POCO.User AddNewUserToDb(User user)
        {
           if (IsDuplicateUser(user.Email.EmailString))
            {
                throw new DuplicateNameException("This email is already taken.");
            }

            UsersTable newUser;

            using (var context = new ServicesEntities())
            {
                newUser = new UsersTable();

                newUser.Address = user.UserDetails.Address;
                newUser.City = user.UserDetails.City;
                newUser.Country = user.UserDetails.Country;
                newUser.Email = user.Email.EmailString;
                newUser.FirstName = user.UserDetails.FirstName;
                newUser.LastName = user.UserDetails.LastName;
                newUser.State = user.UserDetails.State;
                newUser.Zip = user.UserDetails.Zip;

                var referralDetails = new UserReferrals();
                referralDetails.CreatedThruServiceId = 1; // todo don't make this an absolute 1
                referralDetails.ReferralEmail = user.ReferralDetails.ReferralEmail;
                referralDetails.TwoPlusTwoHandle = user.ReferralDetails.TwoPlusTwoHandle;
                //referralDetails.UserId = newUser.UserId;

                var credentials = new UserCredentials();
                credentials.CreatedOn = DateTime.Now;
                credentials.EmailValidated = false;
                //credentials.EmailValidatedOn = null;
                credentials.FailedLoginAttempts = 0;
                credentials.IsLockedOut = false;
                //credentials.LastValidLogin = null;
                credentials.Password = user.Password.PasswordString;
                credentials.PermissionId = 1; // todo don't make this an absolute 1 = user
                credentials.SuccessfulLoginAttempts = 0;
                //credentials.UserId = newUser.UserId; ;

                newUser.Credentials = credentials;
                newUser.ReferralDetails = referralDetails;

                context.UsersTables.AddObject(newUser);
                context.SaveChanges();
            }

            user.UserId = newUser.UserId;

            return user;     

Ответы [ 3 ]

1 голос
/ 27 августа 2010

Попробуйте добавить связанные записи непосредственно в запись UserTable:

newUser.Credentials.Add(credentials);
newUser.ReferralDetails.Add(referralDetails);

Не устанавливать Id.Он будет установлен во время сохранения автоматически.

Редактировать: Кстати.убедитесь, что столбец UserId в таблице UserCredentials не установлен как автоматически созданный в базе данных.

0 голосов
/ 27 августа 2010

EF4 позволит вам включать значения внешнего ключа в качестве скалярных свойств ваших сущностей. Убедитесь, что флажок «Включить внешние ключи» установлен при создании EDM.

Глядя на вашу модель, похоже, вы уже это сделали. Просто установите значения внешнего ключа в явном виде, не нужно совершать двусторонние операции.

0 голосов
/ 27 августа 2010

Взгляните на эти ссылки:

Использование каркаса сущностей для добавления существующих сущностей в коллекцию вновь созданной сущности.

Каксоздать отношения внешнего ключа с Entity Framework?

Entity Framework - вставить новый объект с набором существующих объектов

Ключевые ссылки для EF4:

К счастью, в EF4 мы можем напрямую обновлять отношения благодаря связи с внешним ключом, которая позволяет нам сохранять свойство внешнего ключа внутри классов сущностей.Подробнее см. http://blogs.msdn.com/adonet/archive/2009/11/06/foreign-key-relationships-in-the-entity-framework.aspx.

Кроме того, у нас есть еще одна замечательная функция Self Tracing Entities, которая значительно упрощает n-уровневый шаблон в EF, http://blogs.msdn.com/adonet/archive/2009/11/15/updated-feature-ctp-walkthrough-self-tracking-entities-for-the-entity-framework.aspx.

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