Reputation: 282
I would like to be able to tag my Movie
with a Category
.
public class Movie
{
public virtual ObservableCollection<Category> Categories { get; set; }
public void AddCategory(string name)
{
using (var dbContext = new MyDbContext())
{
var category = dbContext.Categories.SingleOrDefault(x => x.Name == name) ?? new Category(name, dbContext);
Categories.Add(category);
dbContext.SaveChanges();
}
}
}
public class Category()
{
public Category(string name, DbContext dbContext)
{
Name = name;
dbContext.Categories.Add(this);
dbContext.SaveChanges();
}
}
If the category does not exist, it is created and dbContext.Categories.Add(this)
is called inside the Category
c'tor.
There are no errors, but the new Category
is not saved to my Movie.Categories
.
I am guessing it is because my Movie
class belongs to a different context? I am unsure how to structure this.
EDIT: If i was using a database first approach, this would result with a Movie_Categories
table that has a Movie_Id
and a Category_Id
. Why is this so difficult?
Upvotes: 0
Views: 74
Reputation: 282
code that ended up working
public void AddCategory(string name)
{
Category category;
using (var dbContext = new MyDbContext())
category = dbContext.Categories.SingleOrDefault(x => x.Name == name);
using (var dbContext = new MyDbContext())
{
if (category == null)
category = new Category(name, dbContext);
else
dbContext.Categories.Attach(category);
var movie = dbContext.Movies.Single(x => x.Id == Id);
movie.Categories.Add(category);
dbContext.SaveChanges();
}
}
Upvotes: 0
Reputation: 5771
I would structure the model differently. keep the dbcontext out of the model.
public class Movie
{
public string Name { get; set; }
public virtual ICollection<Category> Categories { get; set; }
}
public class Category
{
public string Name {get;set;}
public virtual ICollection<Movie> Movies {get;set;}
}
Notice that I have a virtual collection of Movies within Category. It is this property and the virtual collection in Movie that set the many to many relationship.
You can add then add the category to the collection directly and call SaveChanges.
using (var dbContext = new MyDbContext())
{
var movie = dbContext.Movies.SingleOrDefault(x => x.Name == name);
movie.Categories.Add(new Category() { Name = "Romance"});
dbContext.SaveChanges();
}
The code above will be in some method outside the model classes, probably in your controller or your business layer.
Upvotes: 0
Reputation: 2931
I think what you really want is a many-to-many relationship: One movie can have many categories and also one category can belong to many movies.
So the Category
class needs a public virtual ICollection<Movie> Movies {get; set; }
property.
Your Movie
class could look like this:
public class Movie
{
public virtual ICollection<Category> Categories { get; set; }
public void AddCategory(string name)
{
using (var dbContext = new MyDbContext())
{
// get the movie object from dbContext so that it is attached
var movie = dbContext.Movies.SingleOrDefault(m => m.Name == Name); // or match Movie by Id instead of Name
var category = dbContext.Categories.SingleOrDefault(x => x.Name == name) ?? new Category(name);
movie.Categories.Add(category);
dbContext.SaveChanges();
}
}
}
And the Category
class:
public class Category
{
public virtual ICollection<Movie>() Movies { get; set; }
public string Name { get; set;}
public Category(string name)
{
Name = name;
}
}
Upvotes: 1