Bubble
Bubble

Reputation: 47

EntityFramework create a new object and add existing objects to its navigation property

I am newbie to Entity Framework 5. I try to search in the site, there are some similar questions but no answers.

I have an Announcement object and have navigation property Files

public partial class Announcement
    {
        //remove other properties

        public virtual ICollection<File> Files { get; set; }
    }

In sql server there is Announcement table, File table and an AnnouncementFiles table only has 2 fields [AnnouncementId] and [FileId]. The senario is: I create a new Announcement ,but all files has already existing in database. Code is here:

public void CreateAnnouncement(Announcement announcement, List<Guid> fileIds)
        {
            using (var db = new MyDbEntities())
            {
                var files = db.Files.Where(f => fileIds.Contains(f.Id));
                db.Announcements.Add(announcement);
                foreach (var file in files)
                {
                    announcement.Files.Add(file);
                }
                db.SaveChanges();
            }
        }

and there is error like (my .net framework is not English) cannot update EntitySet“AnnouncementFiles”,because it has a DefiningQuery,but do not have the operate to support currnet element.

I cannot change the table structure, so is there any way to do this? some post says use Attach method but announcement.Files do not have this method. Thanks.

Upvotes: 0

Views: 281

Answers (2)

Clive
Clive

Reputation: 1138

The fileIds.Contains(f.id) cannot be transformed into a sql query. You can construct the expression tree using this link:

http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/095745fe-dcf0-4142-b684-b7e4a1ab59f0/

Upvotes: 0

Malcolm O&#39;Hare
Malcolm O&#39;Hare

Reputation: 4999

You need to define the Linking table in your DbContext's OnModelCreating method.

You should look up defining many to many relationship in entity framework using FluentApi. The code will look something like this

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  base.OnModelCreating(modelBuilder);

  modelBuilder.Entity<Annoucement>()
    .HasMany(x => x.Files)
    .WithMany(x => x.Announcements)
    .Map(x => { 
      x.ToTable("AnnouncementFiles"; 
      x.MapLeftKey("AnnouncementID"); 
      x.MapRightKey("FileID"); 
    });
}

The rest of your code is fine.

Upvotes: 1

Related Questions