开发者

Entity Framework Code First and populating join tables

I been practicing with EF Code First, SQL Express, and ASP.Net MVC3.

When I run the website first the correct tables are generated by the FooInitializer and Student and Image are populated but for some reason the join table (StudentImages) is no开发者_如何转开发t being populated.

What could be the issue?

Tables: Student, Image, and StudentImages

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Image> Images  { get; set; }
}

public class Image
{
    public int Id { get; set; }
    public string Filename { get; set; }
    public string Extension { get; set; }

    public virtual ICollection<Student> Students { get; set; }
}

public class FooInitializer : DropCreateDatabaseIfModelChanges<DBContext>
{

    protected override void Seed(DBContext context)
    {
    var students = new List<Student> {
        new Student { Id = 1, Name = "John" },
        new Student { Id = 2, Name = "Jane" }
    };

    students.ForEach(s => context.Students.Add(s));
    context.SaveChanges();


    var images = new List<Image> {
    new Image { Id = 1, Filename = "IMG_4596.JPG", Extension = ".jpg" },
        new Image { Id = 2, Filename = "IMG_4600.JPG", Extension = ".jpg" }
    };

    images.ForEach(i => context.Images.Add(i));

    students[0].Images.Add(images[0]);
    context.SaveChanges();
    }
}


From what I can tell your Image class does not have a reference to the StudentID. Try adding:

public int StudentID { get; set; } 

to the Image class maybe?

Also having an ICollection would mean that one image could have multiple students - is this correct? Maybe it should be a public virtual Student Student {...}

EDIT: Also I found this, with a many to many relationship (if thats what you need):

In your OnModelCreating() Method:

modelBuilder.Entity<Student>()
    .HasMany(c => c.Images).WithMany(i => i.Students)
    .Map(t => t.MapLeftKey("StudentId")
        .MapRightKey("ImageID")
        .ToTable("StudentImages"));

taken from this link that states:

A many-to-many relationship between the Instructor and Course entities. The code specifies the table and column names for the join table. Code First can configure the many-to-many relationship for you without this code, but if you don't call it, you will get default names such as InstructorInstructorID for the InstructorID column.

EDIT: Here is the code I used the other night, with my implementation of the code first MVC site:

var users = new List<User> 
            {
                new User { UserID = new Guid(), Email = "me@me.com", LastOnline = DateTime.Now, Password = "pword", RegistrationDate = DateTime.Now, SecurityAnswer = "me", SecurityQuestion = "who?", Roles = new List<Role>() },
            };

            users.ForEach(s => context.Users.Add(s));
            context.SaveChanges();

            var roles = new List<Role>
            {
                new Role { RoleID = "Admin", Description = "Administration Users", Users = new List<User>() }

            };
            roles.ForEach(r => context.Roles.Add(r));


            users[0].Roles.Add(roles[0]);
            context.SaveChanges();



            var userLicense = new List<UserLicense>
            {
                new UserLicense { AddDateTime = DateTime.Now, LicenseType = "Farmer", Manufacturer = "Motorola", Model = "Droid", PhoneIdentifier = "c0e4223a910f", UserID = users[0].UserID, User = new User() }

            };
            userLicense[0].User = users[0];
            userLicense.ForEach(u => context.UserLicenses.Add(u));
            context.SaveChanges();

            userLicense[0].User = users[0];
            context.SaveChanges();

Notice in each instantiated item, I am also instantiating a new referenced item within the parent object.

EDIT:

Ok try this:

var students = new List<Student> {
    new Student { Id = 1, Name = "John", Images = new List<Image>() },
    new Student { Id = 2, Name = "Jane", Images = new List<Image>() }
};

students.ForEach(s => context.Students.Add(s));
context.SaveChanges();


var images = new List<Image> {
    new Image { Id = 1, Filename = "IMG_4596.JPG", Extension = ".jpg", Students = new List<Student>()  },
    new Image { Id = 2, Filename = "IMG_4600.JPG", Extension = ".jpg", Students = new List<Student>() }
};

images.ForEach(i => context.Images.Add(i));

students[0].Images.Add(images[0]);
students[1].Images.Add(images[1]);
context.SaveChanges();


Try adding this before saving changes for each student:

foreach (Image i in s1.Images)
    context.ObjectStateManager.ChangeObjectState(i, System.Data.EntityState.Added);

Also try with System.Data.EntityState.Modified.

Hope this works...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜