实体DB将新用户和其他相关数据添加到DB

时间:2010-08-27 01:57:22

标签: c# entity-framework

嘿。 Nooby问题,但实体新。

我正在尝试在一些附加表中创建一个新的用户对象和一些细节,这些表具有新创建的用户ID的外键。

我试图在一次往返中这样做。我是否必须先将用户添加到数据库然后返回,在其他对象上设置用户ID并添加它们。以下是要详细说明的实体模型和代码:

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映射到a   存储生成的列。柱:   '用户ID'。“}

注意:根据书中的示例更新了一些略有不同的代码。

注意2:我已经缩小了添加凭据的问题。

注3:修正了这个问题,我意外地在UserCredentials用户标识上设置了AUTO-INCREMENT。如果有人在这里工作代码:

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 个答案:

答案 0 :(得分:1)

尝试将相关记录直接添加到UserTable记录:

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

不要设置任何ID。它将在保存期间自动设置。

编辑:顺便说一下。确保UserCredentials表中的UserId列未设置为在数据库中自动生成。

答案 1 :(得分:0)

看一下这些链接:

Using the entity framework to add existing entities to a collection on a newly created entity.

How to create foreign key relationships with the Entity Framework?

Entity Framework - insert new object with a collection of existing objects

EF4的关键链接:

  

幸运的是,在EF4中我们可以直接使用   更新由于的关系   允许的外键协会   我们保留外键属性   在实体类中。对于   细节,请看   http://blogs.msdn.com/adonet/archive/2009/11/06/foreign-key-relationships-in-the-entity-framework.aspx

     

此外,我们还有另一个很棒的功能   自我追踪实体,使得   EF中的n层模式更容易,   http://blogs.msdn.com/adonet/archive/2009/11/15/updated-feature-ctp-walkthrough-self-tracking-entities-for-the-entity-framework.aspx

答案 2 :(得分:0)

EF4允许您将外键值包含为实体的标量属性。确保在创建EDM时选中“包含外键”复选框。

看看你的模型,看起来你已经做到了。只需明确设置外键值,无需往返。