ASP.NET MVC使用Ninject,实体框架4 code-一次CTP 5,模式3应用 [英] ASP.NET MVC 3 Application using Ninject, Entity Framework 4 Code-First CTP 5, Patterns

查看:158
本文介绍了ASP.NET MVC使用Ninject,实体框架4 code-一次CTP 5,模式3应用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

香港专业教育学院试图建立与上述技术的一些基地项目。我想最大的灵活性和可测试性,所以我试图用图案一路上,使这个作为未来项目基地。然而,它看起来
什么是错的或什么的,我真的需要帮助这里。所以,我有两个问题:

ive tried to build some base project with above technologies. I wanted maximum flexibility and testability so i tried to use patterns along the way to make this as a base for future projects. However, it seem something is wrong or whatever and i really need help here. So i have two questions :

1 - 这有什么错我目前的code?伊夫正确应用模式?任何建议或recommandation,这将导致我在正确的方向吗?

1- Is there anything wrong with my current code ? Ive applied patterns correctly ? Any suggestions or recommandation that would lead me in the right direction ?

2 - 为什么这样做code实际连接到数据库,创建它,但犯规支持插入即使我执行操作进行校正? (看帖子的末尾有关此错误的详细信息)的 ** **固定

2- Why do this code actually connect to the database, create it, but doesnt support insert even if i perform the corrects operation ? (Look at the end of the post for details about this error) ** FIXED **

我相信这也可以帮助别人,因为我为了做出正确的东西了还没有找到足够的信息。我是pretty肯定很多永世的尝试做正确的方式,并不一定喜欢我,如果我在做什么是正确的。

I believe this could also help others since i havent found enough informations in order to make something up correctly. I am pretty sure lots of poeple try to do it the right way and are not sure like me if what i am doing is right.

我有两个实体:评论和审查

I have two entities : Comment and Review

COMMENT

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; }
}

我建立了为他们每个人的这样一个基础库:

I built up a base repository for each of them this way :

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);
}

所以,我收到从抽象类仿制药业务,加上具体操作:

So i am getting the generics operations from the abstract class plus the specific operations :

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>();
 }
}

当你想通了,我也用一个数据库工厂将生产数据库方面:

As you figured out, i also use a database factory will produce the database context :

DATABASE厂

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();
 }
}

一次性的(某些扩展方法...)

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 
 }
 */
}

和结束,我有我的工作单位......

And to finish, i have my unit of work....

工作单元

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接口绑定:

I also binded using Ninject the interfaces :

NINJECT控制器工厂

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>();
  }
 }
}

然而,当我调用构造函数(默认操作)...

However, when i call in the constructor (The default action) ...

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());
        }

    }

这似乎是创建数据库,但doesnt't插在EF4数据库什么。这似乎使我想通了这个问题。而在看数据库对象..连接状态被关闭,服务器版本抛出这样的例外:

This seem to create the database but doesnt't insert anything in the database in EF4. It seem that i may figured out the problem.. while looking at the database object.. the connection state is closed and server version throw an exception of this kind :

ServerVersion = '(((System.Data.Entity.DbContext (_database)).Database.Connection).ServerVersion' threw an exception of type 'System.InvalidOperationException'

我在做正确的事情?有什么错在哪建IVE?

I am doing the right things ? Is there anything wrong in what ive built ?

此外,如果您有任何关于code I贴recommandation,我会很高兴。我只是试图将学习构建任何类型的应用程序在MVC 3,正确的方式,我希望有一个良好的开始。

Also if you have recommandation about the code i posted, i would be glad. I am just trying to the learn the right way for building any kind of application in MVC 3. I want a good a start.

我使用的:


  • 实体框架4 code-首先

  • Entity Framework 4 with Code-First

ASP.NET MVC 3

ASP.NET MVC 3

Ninject作为DI容器

Ninject as DI Container

SQL Server的防爆preSS(非R2)

SQL Server Express (not R2)

Visual Studio 2010中的Web防爆preSS

Visual Studio 2010 Web Express

感谢很多的帮助!

推荐答案

好恶。这一次是偷偷摸摸的。其实我不知道ninject竟有如此我不能弄明白的时候了。

Eww. This one was sneaky. Actually i don't know ninject much so i couldnt figure it out right away.

我发现这是由发现ninject实际拍摄DatabaseFactory两个实例,一个用于存储库和一个工作单元相关错误的第二个问题的解决方案。实际上,误差不是问题。这是在对象数据库内部错误,但它的正常使用我的实体框架认为因为即时通讯。

I found the solution for the SECOND question which was related to the error by finding that ninject actually shoot two instance of the DatabaseFactory, one for the repository and one for the unit of work. Actually, the error was not the problem. It was an internal error in the object database but its normal i think since im using Entity Framework.

真正的问题是,Ninject是有约束力IDatabaseFactory两个不同的实例,从而导致2连接打开。

The real problem was that Ninject was binding two different instance of IDatabaseFactory which lead to 2 connection open.

审查加入到_reviewRepostory第一盘这是使用数据库的第一个实例。

The review was added to the first set in _reviewRepostory which was using the first instance of the Database.

在调用commit工作单位..它没有保存由于这样的事实,在这个数据库实例审查wasnt。事实上,工作单位,称为这导致自ninject发送它的一个新实例创建一个新的实例databasefactory。

When calling commit on the unit of work.. it saved nothing due to the fact that the review wasnt on this database instance. In fact, the unit of work called the databasefactory which lead to creating a new instance since ninject sent a new instance of it.

要修复它只需使用:

 Bind<IDatabaseFactory>().To<DatabaseFactory>().InSingletonScope();

而不是

Bind<IDatabaseFactory>().To<DatabaseFactory>();

和现在所有的系统工作正常!

And now all the system work correctly!

现在,很想就这是,如果有什么问题我目前的code中的第一个问题一些答案?伊夫正确应用模式?任何建议或推荐,这将导致我在正确的方向吗?

这篇关于ASP.NET MVC使用Ninject,实体框架4 code-一次CTP 5,模式3应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆