加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

实体框架4 – ASP.NET MVC 3应用程序使用Ninject,实体框架4代码

发布时间:2020-12-16 00:31:52 所属栏目:asp.Net 来源:网络整理
导读:试图用上述技术构建一些基础项目。我想要最大的灵活性和可测试性,所以我试图使用模式,使其成为未来项目的基
试图用上述技术构建一些基础项目。我想要最大的灵活性和可测试性,所以我试图使用模式,使其成为未来项目的基础。但是,似乎
有什么不对劲的,我真的需要帮助。所以我有两个问题:

1-当前的代码有什么问题吗? Ive是否正确应用模式?有什么建议或意见,会导致我走向正确的方向?

2-为什么这个代码实际上连接到数据库,创建它,但即使我执行正确的操作也不支持插入? (有关此错误的详细信息,请查看帖子的结尾)** FIXED **

我相信这也可以帮助别人,因为我没有找到足够的信息,以使正确的东西。我很确定很多人都试图以正确的方式做到这一点,如果我正在做的事情是对的,那么我不知道如何。

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

评论

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

我以这种方式为每个人建立了一个基础仓库:

一般报告

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

如你所知,我也使用数据库工厂将产生数据库上下文:

数据库

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

数据库

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控制器厂

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'

我在做正确的事情吗? ive建造有什么问题吗?

另外如果你有关于我发布的代码的推荐,我会很高兴。我只是想在MVC 3中学习正确的方式来构建任何类型的应用程序。我想要一个很好的开始。

我用 :

>实体框架4与代码优先
> ASP.NET MVC 3
>作为DI容器的NINject
> SQL Server Express(不是R2)
> Visual Studio 2010 Web Express

非常感谢您的帮助!

解决方法

好恶。这个鬼鬼祟祟其实我不知道ninject很多,所以我不能立即计算出来。

我发现第二个问题的解决方案是与错误相关的,发现该ninject实际上拍摄了DatabaseFactory的两个实例,一个用于存储库,另一个用于工作单元。其实这个错误不是问题。这是对象数据库中的内部错误,但正常情况下,我认为自从使用实体框架。

真正的问题是Ninject绑定了两个不同的IDatabaseFactory实例,导致2个连接打开。

该审查已添加到_reviewRepostory中第一个使用数据库的第一个实例的集合。

当在工作单元上调用commit时,它没有保存任何内容,这是因为该事件不在该数据库实例上。事实上,这个工作单元称为数据库,它导致创建一个新的实例,因为ninject发送了一个新的实例。

要解决它,只需使用:

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

代替

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

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

现在,对于第一个问题,我会喜欢一些答案,那就是我现在的代码有什么问题吗? Ive是否正确应用模式?有什么建议可以引导我走向正确的方向?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读