Reputation: 581
I am creating an application in which I use Entity Framework. I have 2 classes with one-to-many relation .I decided to use a design pattern Repository as far as I know it is a good practice. My Interface:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace DataAccess.Repository
{
public interface IRepository<T>
{
void Insert(T entity);
void Delete(T entity);
IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate);
IEnumerable<T> GetAll();
T GetById(int id);
}
}
My class
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using DataAccess.Repository;
namespace DataAccess
{
public class Repository<T> : IRepository<T> where T : class
{
protected DbSet<T> DbSet;
public Repository(DbContext datacontext)
{
//DbContext.Set Method (Type)
//Returns a non-generic DbSet instance for access to entities of the given type in the context and the underlying store.
DbSet = datacontext.Set<T>();
}
public void Insert(T entity)
{
DbSet.Add(entity);
}
public void Delete(T entity)
{
DbSet.Remove(entity);
}
public IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate)
{
return DbSet.Where(predicate);
}
public IEnumerable<T> GetAll()
{
return DbSet;
}
public T GetById(int id)
{
return DbSet.Find(id);
}
}
}
And this is my two model classes
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Model
{
public class Book
{
public int BookId { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public string Ganre { get; set; }
public int Size { get; set; }
public string Path { get; set; }
}
}
and
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Model
{
public class Category{
public Category()
{
Books = new List<Book>();
}
public int CategoryId { get; set; }
public string CategoryName { get; set; }
virtual public ICollection<Book> Books { get; set; }
}
}
But my question is, how to add the book to a category? This is an example of my implementation but book is not added to the category. But when I want to get all the books or all categories everything works fine.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
using Model;
using DataAccess;
namespace TestDB
{
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(
new DropCreateDatabaseIfModelChanges<BookShelfContext>());
using (var db = new BookShelfContext())
{
var book = new Book
{
Author = "Author Name",
Ganre = "Ganre",
Name = "Book Name",
Path = @"Path",
Size = 10
};
var category = new Category
{
CategoryName = "Interesting"
};
var bookrepository = new Repository<Book>(db);
var categoryrepository = new Repository<Category>(db);
IEnumerable<Book> books = bookrepository.GetAll();
IEnumerable<Category> categories = categoryrepository.GetAll();
//get all books for example
foreach (var b in books)
{
Console.WriteLine(b.Name);
}
}
Console.ReadKey();
}
}
}
Thank you very much for your help. Have a nice day and less bugs)
Upvotes: 6
Views: 6211
Reputation: 877
Add the context to your Repository so that you can implement the SaveChanges method:
protected readonly DbContext context;
public Repository(DbContext datacontext)
{
DbSet = datacontext.Set<T>();
context = datacontext;
}
public void SaveChanges()
{
context.SaveChanges();
}
Then in order to add a book to an existing BookCategory simply add the book to the Category's collection and save the category:
var categoryrepository = new Repository<Category>(db);
var myCategory = categoryrepository.GetById(1);
myCategory.Books.Add(book);
categoryrepository.SaveChanges();
Remember to call SaveChanges in order to persist the data in the database. EF is smart enough to notice that you added a child to the category and it will mark it as Added. On saving changes it will insert it to the database together with the foreign keys that it needs.
Upvotes: 2
Reputation: 746
I think you need to add a category property to the book object
public virtual Category BookCategory { get; set; }
so that the one to many relationship is implemented
Upvotes: 0