Я пытался создать базовый проект с использованием вышеуказанных технологий. Мне нужна была максимальная гибкость и тестируемость, поэтому я попытался использовать шаблоны в процессе, чтобы сделать это основой для будущих проектов. Однако кажется Мне нужна была максимальная гибкость и тестируемость, поэтому я попытался использовать шаблоны, чтобы сделать это основой для будущих проектов. Однако ...
Я пытался создать базовый проект с использованием вышеуказанных технологий. Мне нужна была максимальная гибкость и тестируемость, поэтому я попытался использовать шаблоны, чтобы сделать это основой для будущих проектов. Однако кажется Мне нужна была максимальная гибкость и тестируемость, поэтому я попытался использовать шаблоны, чтобы сделать это основой для будущих проектов. Однако ...
Я пытался создать базовый проект с использованием вышеуказанных технологий. Мне нужна была максимальная гибкость и тестируемость, поэтому я попытался использовать шаблоны, чтобы сделать это основой для будущих проектов. Однако кажется что-то не так или что-то в этом роде, и мне действительно нужна помощь. Итак, у меня два вопроса:
Что-то не так с моим текущим кодом? Я правильно нанесла узоры? Любые предложения или рекомендации, которые могли бы привести меня в правильном направлении?
Почему этот код на самом деле подключается к базе данных, создает ее, но не поддерживает вставку, даже если я выполняю операцию исправления? (Подробности об этой ошибке см. В конце сообщения) ИСПРАВЛЕНО
Я считаю, что это также может помочь другим, так как я не нашел достаточно информации, чтобы что-то исправить. Я почти уверен, что многие люди пытаются делать это правильно, и не уверены, как я, правильно ли то, что я делаю.
У меня две сущности: Комментарий и Обзор
КОММЕНТАРИЙ
public class Comment
{
[Key]
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Author { get; set; }
public virtual string Body { get; set; }
}
ОБЗОР
public class Review
{
[Key]
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Author { get; set; }
public virtual string Body { get; set; }
public virtual bool Visible { get; set; }
public IEnumerable<Comment> Comments { get; set; }
}
Я создал базовый репозиторий для каждого из них следующим образом:
GENERIC REPOSITORY
public abstract class EFRepositoryBase<T> : IRepository<T> where T : class
{
private Database _database;
private readonly IDbSet<T> _dbset;
protected IDatabaseFactory DatabaseFactory { get; private set; }
protected Database Database { get { return _database ?? (_database = DatabaseFactory.Get()); } }
public EFRepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
_dbset = Database.Set<T>();
}
public virtual void Add(T entity)
{
_dbset.Add(entity);
}
public virtual void Delete(T entity)
{
_dbset.Remove(entity);
}
public virtual T GetById(long id)
{
return _dbset.Find(id);
}
public virtual IEnumerable<T> All()
{
return _dbset.ToList();
}
}
Для конкретных операций я использую интерфейс:
public interface IReviewRepository : IRepository<Review> {
// Add specific review operations
IEnumerable<Review> FindByAuthor(string author);
}
Итак, я получаю общие операции из абстрактного класса плюс конкретные операции:
public class EFReviewRepository : EFRepositoryBase<Review>, IReviewRepository
{
public EFReviewRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{ }
public IEnumerable<Review> FindByAuthor(string author)
{
return base.Database.Reviews.Where(r => r.Author.StartsWith(author))
.AsEnumerable<Review>();
}
}
Как вы поняли, Я также использую фабрику базы данных для создания контекста базы данных:
DATABASE FACTORY
public class DatabaseFactory : Disposable, IDatabaseFactory
{
private Database _database;
public Database Get()
{
return _database ?? (_database = new Database(@"AppDb"));
}
protected override void DisposeCore()
{
if (_database != null)
_database.Dispose();
}
}
DISPOSABLE (Некоторые методы расширений ...)
public class Disposable : IDisposable
{
private bool isDisposed;
~Disposable()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!isDisposed && disposing)
{
DisposeCore();
}
isDisposed = true;
}
protected virtual void DisposeCore()
{
}
}
DATABASE
public class Database : DbContext
{
private IDbSet<Review> _reviews;
public IDbSet<Review> Reviews
{
get { return _reviews ?? (_reviews = DbSet<Review>()); }
}
public virtual IDbSet<T> DbSet<T>() where T : class
{
return Set<T>();
}
public Database(string connectionString)
: base(connectionString)
{
//_reviews = Reviews;
}
public virtual void Commit()
{
base.SaveChanges();
}
/*
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// TODO: Use Fluent API Here
}
*/
}
И, наконец, у меня есть моя единица работы ....
ЕДИНИЦА РАБОТЫ
public class UnitOfWork : IUnitOfWork
{
private readonly IDatabaseFactory _databaseFactory;
private Database _database;
public UnitOfWork(IDatabaseFactory databaseFactory)
{
_databaseFactory = databaseFactory;
}
protected Database Database
{
get { return _database ?? (_database = _databaseFactory.Get()); }
}
public void Commit()
{
Database.Commit();
}
}
Я также связал с помощью Ninject интерфейсы:
NINJECT CONTROLLER FACTORY
public class NinjectControllerFactory : DefaultControllerFactory
{
// A Ninject "Kernel" is the thing that can supply object instances
private IKernel kernel = new StandardKernel(new ReviewsDemoServices());
// ASP.NET MVC calls this to get the controller for each request
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
return null;
return (IController)kernel.Get(controllerType);
}
private class ReviewsDemoServices : NinjectModule
{
public override void Load()
{
// Bindings...
Bind<IReviewRepository>().To<EFReviewRepository>();
Bind<IUnitOfWork>().To<UnitOfWork>();
Bind<IDatabaseFactory>().To<DatabaseFactory>();
Bind<IDisposable>().To<Disposable>();
}
}
}
Однако, когда я вызываю конструктор (действие по умолчанию) ...
public class ReviewController : Controller
{
private readonly IReviewRepository _reviewRepository;
private readonly IUnitOfWork _unitOfWork;
public ReviewController(IReviewRepository postRepository, IUnitOfWork unitOfWork)
{
_reviewRepository = postRepository;
_unitOfWork = unitOfWork;
}
public ActionResult Index()
{
Review r = new Review { Id = 1, Name = "Test", Visible = true, Author = "a", Body = "b" };
_reviewRepository.Add(r);
_unitOfWork.Commit();
return View(_reviewRepository.All());
}
}
Кажется, создается база данных, но ничего не вставляет в базу данных в EF4. Кажется, я понял проблему ... глядя на объект базы данных ... состояние подключения закрыто, и версия сервера выдает исключение такого рода:
ServerVersion = '(((System.Data.Entity.DbContext (_database)).Database.Connection).ServerVersion' threw an exception of type 'System.InvalidOperationException'
Я поступаю правильно? Что-то не так в том, что я построил?
Также, если у вас есть рекомендации по опубликованному мной коду, я был бы рад. Я просто пытаюсь найти правильный способ создания любого приложения в MVC 3. Мне нужно хорошее начало.
Я использую:
Entity Framework 4 с Code-First
ASP.NET MVC 3
Ninject как контейнер DI
SQL Server Express (не R2)
Visual Studio 2010 Web Express