I am trying a MVC project with repository pattern and unit of work.
The following is from my InitOfWork
public interface IUnitOfWork
{
IRepository<User> UserRepository { get; }
void Save();
}
and this is from UnitOfWork
public class UnitOfWork:IUnitOfWork, IDisposable
{
private JNContext context = new JNContext();
private bool disposed = false;
private IRepository<User> userRepository;
public IRepository<User> UserRepository
{
get
{
if (this.userRepository == null)
{
this.userRepository = new Repository<User>(this.context);
}
return this.userRepository;
}
}
public void Save()
{
this.context.SaveChanges();
}}
The following line in UnitOfWork generates the error 'Cannot implicitly convert from Repository to IRepository
this.userRepository = new Repository<User>(this.context);
What am I missing. I cannot find an answer and I am stuck the entire day.
Try something like this
public interface IRepository<T> where T : class
{
IQueryable<T> Entities { get; }
void Remove(T entity);
void Add(T entity);
}
public class GenericRepository<T> : IRepository<T> where T : class
{
private readonly MyDbContext _dbContext;
private IDbSet<T> _dbSet => _dbContext.Set<T>();
public IQueryable<T> Entities => _dbSet;
public GenericRepository(MyDbContext dbContext)
{
_dbContext = dbContext;
}
public void Remove(T entity)
{
_dbSet.Remove(entity);
}
public void Add(T entity)
{
_dbSet.Add(entity);
}
}
Found a good article about it here: https://medium.com/#utterbbq/c-unitofwork-and-repository-pattern-305cd8ecfa7a
Related
I am trying to set the initialization of my db by code, so that when the application is deployed the database is updated to the latest migration.
My DB Context is as follows:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ApplicationDbContext, MyDbMigrationsConfiguration>());
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Topic>().ToTable("Topics");
modelBuilder.Entity<Attachment>().ToTable("Attachments");
modelBuilder.Entity<Subscription>().ToTable("Subscriptions");
}
public DbSet<Topic> Topics { get; set; }
public DbSet<Subscription> Subscriptions { get; set; }
public DbSet<Attachment> Attachments { get; set; }
}
}
My Migration configuration is this:
internal sealed class MyDbMigrationsConfiguration : DbMigrationsConfiguration<ApplicationDbContext>
{
public MyDbMigrationsConfiguration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(ApplicationDbContext context)
{}
}
And in my startup I have:
public partial class Startup {
public void Configuration(IAppBuilder app) {
ConfigureAuth(app);
using (var dbContext = new ApplicationDbContext())
{
dbContext.Database.CreateIfNotExists();
dbContext.Database.Initialize(force: false);
}
}
}
Now when I call dbContext.Database.Initialize(force: false); I am getting an error about one of the tables being already existing.
But I thought the initializer should check whether the database is already updated or not and apply the migrations accordingly. What am I doing wrong?
I have model:
public class Department
{
public int DepartmentID { get; set; }
[Required]
[UniqueDepartmentName]
public string Name { get; set; }
public List<Person> Persons { get; set; }
}
And DBcontext:
public class InstituteContext : DbContext
{
public InstituteContext (DbContextOptions<InstituteContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Department>().HasIndex(p => p.Name).IsUnique();
}
public DbSet<Institute.Models.Department> Department { get; set; }
}
As you see property "NAME" i make unique.
For validation i create My validation Attribute:
public class UniqueDepartmentName : ValidationAttribute
{
public override bool IsValid(object value)
{
var db = new InstituteContext();
}
}
But i can not create instance of InstituteContext, because constructor need parameters.
How i can create instance of InstituteContext? Or what should i pass to constructor in parameters?
Try this:
public class UniqueDepartmentName : ValidationAttribute
{
public override bool IsValid(object value)
{
var connectionString = "Your ConnectionString"
var options = new DbContextOptionsBuilder<InstituteContext>()
.UseSqlServer(new SqlConnection(connectionString)).Options;
using (var dbContext = new BloggingContext(options))
{
// Do necessary staffs here with dbContext
}
}
}
Your DbContextOptions method is in the wrong place, your constructor can be empty, and you need to add the method OnConfiguring, which receives the DbContextOptions.
Something like:
public DbSet<Department> Department { get; private set; }
protected override void OnConfiguring(DbContextOptionsBuilder options) {
// In my case I'm passing the connection string in this method below
options.UseSqlServer("Data Source=DATABASEIP;Initial Catalog=DATABASETABLE;" +
"User ID=USER;Password=PASSWORD");
}
I am trying to use Repository/UoW Patternin a .net core project . I have looked at many implementations across web . In all the implementations repositories are created as properties in IUnitOfWork.
In Future if we have 50 Repositories we need to have 50 properties in the Unit of Work . Could anyone suggest a better approach for implementing Repository/UoW.
Please Find below the code snippets of approach i have implemented currently.
IUnitOfWork.cs
IStudentRepository Student { get; set; }
IClassRepository Class { get; set; }
void Complete();
UnitOfWOrk.cs
public class unitofwork {
private readonly CollegeContext _context;
IStudentRepository Student { get; set; }
IClassRepository Class { get; set; }
public UnitOfWork(CollegeContext CollegeContext)
{
this._context = CollegeContext;
Student = new StudentRepository(_context);
Class = new ClassRepository(_context);
}
public void Complete()
{
return _context.SaveChanges();
}
}
Student and Class Repositories Inherit From a generic Repository class and IStudentRepository and IClassRepository respectively.
StudentRepository.cs
public class StudentRepository : Repository<Student> , IStudentRepository
{
private readonly CollegeContext context;
private DbSet<Student> entities;
public StudentRepository(CollegeContext context) : base(context)
{
this.context = context;
entities = context.Set<Student>();
}
}
Property-per-Repository is not convenient in some cases as you said. I generally use some sort of factory method in UoW class as below:
public class unitofwork
{
private readonly CollegeContext _context;
IStudentRepository Student { get; set; }
IClassRepository Class { get; set; }
public UnitOfWork(CollegeContext CollegeContext)
{
this._context = CollegeContext;
}
public T CreateRepository<T>() where T : IRepository
{
IRepository repository = null;
if(typeof(T) == typeof(IStudentRepository))
repository = new StudentRepository(_context);
......
......
else
throw new XyzException("Repository type is not handled.");
return (T)repository;
}
public void Complete()
{
return _context.SaveChanges();
}
}
public interface IRepository
{
Guid RepositoryId { get; }
}
My IRepository just hold a simple property. You may extend this interface as per your needs.
Hi i am using MVC 5 + EF6 and want to register MVC 5 Application User and other specific types using Unity 3 but i am getting errors.
My Context Class:
public class ProjectContext : IdentityDbContext<ApplicationUser>
{
public ProjectContext()
: base("ProjectContext")
{
}
public DbSet<User> Users { get; set; }
public DbSet<UserProfile> UserProfile { get; set; }
public virtual void Commit()
{
base.SaveChanges();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
Controller Class:
public class AccountController : Controller
{
private UserManager<ApplicationUser> UserManager;
private IUserService userService;
private IUserProfileService userProfileService;
public AccountController(IUserService userService, IUserProfileService userProfileService, UserManager<ApplicationUser> userManager)
{
this.userService = userService;
this.userProfileService = userProfileService;
this.UserManager = userManager;
}
}
I have used the following registration in combinations but i am getting errors
--> ProjectArchitecture.Web.Controllers.AccountController does not have a constructor that takes the parameters (). When all 1-4 are commented above
--> The type DbConnection does not have an accessible constructor.
Unity Registration Code:
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>();
container.RegisterType<IRoleStore<IdentityRole>, RoleStore<IdentityRole>>();
container.RegisterType<AccountController>(new InjectionConstructor());
container.RegisterInstance(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ProjectEntities())));
I'm new to the forum and in the "world" of programming. I bumped into a problem while creating a game with SignalR Web technology and it is expressed in terms of access to the database (using EF) with multiple requests from UI-a. What is the best solution using the repository pattern? The decision to me at this stage is added Lock {} structure in each method, which accesses the database. How can I avoid blocking requests to a server?
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
T GetById(object id);
void Add(T item);
void Update(T item);
void Delete(T item);
void Delete(object id);
}
public class DBRepository<T> : IRepository<T> where T : class
{
private DbContext DbContext;
private DbSet<T> Entities
{
get
{
return this.DbContext.Set<T>();
}
}
public DBRepository(DbContext context)
{
this.DbContext = context;
}
public IQueryable<T> GetAll()
{
return Entities.AsQueryable();
}
.....
public class TicTacToeContext : DbContext
{
public DbSet<Game> Games { get; set; }
public DbSet<Guess> Guesses { get; set; }
public DbSet<Message> Messages { get; set; }
public DbSet<MessageState> MessageStates { get; set; }
public DbSet<MessageType> MessageTypes { get; set; }
public DbSet<User> Users { get; set; }
public TicTacToeContext()
: base("TicTacToeDb")
{
}
public interface IGameService
{
void CreateGame(CreateGameModel gameModel);
void JoinGame(JoinGameModel gameModel);
...
public abstract class BaseService
{
public IRepository<User> UserRepository;
public IRepository<Game> GameRepository;
...
public class GameService : BaseService, IGameService
{
public GameService(IRepository<Game> gameRepositort, IRepository<User> userRepository, ISessionService sessionService)
{
this.UserRepository = userRepository;
this.GameRepository = gameRepositort;
}
public void CreateGame(CreateGameModel gameModel)
{
....
}
public class TicTacToeHub : Hub
{
IUserService UserServise;
IGameService GameServise;
private static object _syncRoot = new object();
public TicTacToeHub(IUserService userService, IGameService gameService)
{
this.UserServise = userService;
this.GameServise = gameService;
}
.....
public void ReturnOpenGamesToClient(string sessionKey)
{
IEnumerable<GameModel> openGames;
lock (_syncRoot)
{
openGames = GameServise.GetOpenGames(sessionKey).ToList();
}
Clients.Caller.updateOpenGamesList(openGames);
}
Why locks? You use a DB and only update one entity (No transaction scope needed).
Locks needs to be used for Inmemory types like IList or IDictionary otherwise it will crash when one request reads and another one writes. But SQL takes care of this for you