gpt4 book ai didi

entity-framework-4 - 使用 Ninject、Entity Framework 4 Code-First CTP 5、模式的 ASP.NET MVC 3 应用程序

转载 作者:行者123 更新时间:2023-12-03 14:11:58 27 4
gpt4 key购买 nike

我尝试使用上述技术构建一些基础项目。我想要最大的灵 active 和可测试性,因此我尝试在此过程中使用模式来将其作为 future 项目的基础。然而,似乎
出了点问题或其他什么,我真的需要帮助。所以我有两个问题:

  • 我当前的代码有什么问题吗?我正确地应用了模式?有什么建议或建议可以引导我朝着正确的方向前进吗?
  • 为什么这段代码实际上连接到数据库,创建它,但即使我执行了更正操作也不支持插入? (有关此错误的详细信息,请查看帖子末尾)固定

  • 我相信这也可以帮助其他人,因为我没有找到足够的信息来正确地弥补一些东西。我很确定很多人都试图以正确的方式做这件事,但不确定我所做的是否正确。

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

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

    对于 具体操作 ,我使用一个接口(interface):
    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();
    }
    }

    一次性(一些扩展方法...)
    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 绑定(bind)了接口(interface):

    NINJECT Controller 厂
    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'

    我在做正确的事吗?我 build 的东西有什么问题吗?

    此外,如果您对我发布的代码有建议,我会很高兴。我只是想学习在 MVC 3 中构建任何类型的应用程序的正确方法。我想要一个好的开始。

    我用 :
  • 具有代码优先的 Entity Framework 4
  • ASP.NET MVC 3
  • Ninject 作为 DI 容器
  • SQL Server Express(不是 R2)
  • Visual Studio 2010 网络速递
  • 最佳答案

    哇。这个是偷偷摸摸的。实际上我不太了解ninject,所以我无法立即弄清楚。

    通过发现 ninject 实际上拍摄了 DatabaseFactory 的两个实例,一个用于存储库,一个用于工作单元,我找到了与错误相关的第二个问题的解决方案。实际上,错误不是问题。这是对象数据库中的内部错误,但我认为这是正常的,因为我使用的是 Entity Framework 。

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

    评论被添加到 _reviewRepostory 中的第一个集合中,该集合正在使用数据库的第一个实例。

    在工作单元上调用提交时.. 由于审查不在此数据库实例上,因此它没有保存任何内容。事实上,工作单元称为 databasefactory 导致创建一个新实例,因为 ninject 发送了它的一个新实例。

    要修复它,只需使用:

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

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

    现在所有系统都可以正常工作!

    现在,是否会喜欢关于第一个问题的一些答案,即我当前的代码是否有问题?我正确地应用了模式?有什么建议或建议可以引导我朝着正确的方向前进吗?

    关于entity-framework-4 - 使用 Ninject、Entity Framework 4 Code-First CTP 5、模式的 ASP.NET MVC 3 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4782364/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com