Вопрос

I've got an MVC4 project that uses Entity Framework 5 (code-first) with code-first migrations. The site uses SimpleMembership. I'm attempting to seed the users table but am encountering errors relating to the setting of the navigation property.

I've got an Account and User model. SimpleMembership uses the User model as my custom users table. The relationship is a one-to-many with there being one Account per User but many Users per Account. I am attempting to set the User to Account relationship at seed-time but am unable to.


The models (extraneous properties omitted):

public class User
{
    [Key]
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Description { get; set; }

    public int AccountId { get; set; }
    public virtual Account Account { get; set; }
}

public class Account
{
    [Key]
    public int AccountId { get; set; }
    public string Name { get; set; }

    // Account has many users but only one "admin" user. ID manually set.
    // Nullable because of chicken / egg problem (user requires account, account requires user)
    public int? AdminUser { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

Seed method:

protected override void Seed(MyProject.Data.MyContext context)
{
    WebSecurity.InitializeDatabaseConnection("MyContext", "Users", "UserId", "UserName", autoCreateTables: true);

    Account adminAccount = new Account()
    {
        Name = "Dev",
        Description = "Dev account"
    };

    context.Accounts.AddOrUpdate(adminAccount);

    if (!WebSecurity.UserExists("dev@dev.com"))
    {
        WebSecurity.CreateUserAndAccount("dev@dev.com", "password", new User()
        {
            Email = "dev@dev.com",
            FirstName = "Dev",
            LastName = "Guy"
            // Problematic properties - see below
            // Account = adminAccount,
            // AccountId = adminAccount.AccountId
        });
    }
}

Where I appear to be running intro trouble is when I call WebSecurity.CreateUserAndAccount:

  1. If I attempt to include the navigation property Account = adminAccount I get the error:

    "No mapping exists from object type MyProject.Models.Account to a known managed provider native type."

  2. If I attempt to include just the FK reference AccountId = adminAccount.AccountId I get the error:

    "Invalid column name 'Account'"

  3. If I don't include Account or AccountId, I also get

    "Invalid column name 'Account'"


I should point out that I had this working with just navigation properties in my classes. When I added foreign key properties, everything just blew up (there are errors related to FKs but I cannot reproduce them well enough to post them here and they were likely related to my database needing to be re-created. I'm seeing the above-errors with a fresh, table-less database.

Also, I'm using SQL Azure as my SQL database.

This seems like a common use case for SimpleMembership; I don't know what it's giving me so much trouble.

Это было полезно?

Решение

As I thought, it was a very silly error. Basically Account wasn't yet created in the database before I tried to assign its ID to the new User.

When I attempt to manually insert data into the database, I got the following error:

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Users_dbo.Accounts_AccountId". The conflict occurred in database "projectdev", table "dbo.Accounts", column 'AccountId'.

After some digging I found that the AccountID I was assigning to the User was incorrect, and when I changed the ID to the correct one it worked just fine. That led me to realize that I wasn't committing the Account context changes to the database before trying to assign its AccountId to the Users table.

I simply added context.SaveChanges(); after context.Accounts.AddOrUpdate(adminAccount); and everything worked just fine.

Good grief...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top