Ive ha provato a creare un progetto di base con le tecnologie di cui sopra. Volevo la massima flessibilità e verificabilità, così ho provato a utilizzare i pattern lungo il percorso per renderlo una base per i progetti futuri. Tuttavia, sembra che qualcosa sia sbagliato o qualsiasi altra cosa e ho davvero bisogno di aiuto qui. Quindi ho due domande:ASP.NET MVC 3 Applicazione che utilizza Ninject, Entity Framework 4 Code-First CTP 5, Pattern
1- C'è qualcosa di sbagliato nel mio codice corrente? Ho applicato i pattern correttamente? Qualche suggerimento o raccomandazione che mi porterebbe nella giusta direzione?
2- Perché questo codice si collega effettivamente al database, lo crea, ma non supporta l'inserimento anche se eseguo l'operazione di correzione? (Vedi alla fine del post per ulteriori informazioni su questo errore) ** ** fisso
Credo che questo potrebbe anche aiutare gli altri in quanto i havent trovato sufficienti informazioni per poter fare qualcosa in modo corretto. Sono abbastanza sicuro che molte persone provano a farlo nel modo giusto e non sono sicuro come me se quello che sto facendo è giusto.
ho due entità: commento e recensione
COMMENTO
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; }
}
RASSEGNA
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; }
}
ho costruito un deposito di base per ciascuno di loro in questo modo:
DEPOSITO GENERICO
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();
}
}
Per operazioni specifiche, io uso un'interfaccia:
public interface IReviewRepository : IRepository<Review> {
// Add specific review operations
IEnumerable<Review> FindByAuthor(string author);
}
Quindi io sono sempre le operazioni di farmaci generici dalla classe astratta più le operazioni specifiche:
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>();
}
}
Come hai capito, uso anche un database di fatto ry produrrà il contesto di database:
DATABASE FABBRICA
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();
}
}
MONOUSO (Alcuni metodi di estensioni ...)
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
}
*/
}
E per finire, ho la mia unità di lavoro ....
UNITA DI LAVORO
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();
}
}
Ho anche rilegato utilizzando Ninject le interfacce:
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>();
}
}
}
Tuttavia, quando chiamo nel costruttore (The azione predefinita) ...
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());
}
}
Questo sembra creare il database ma non inserisce nulla nel database in EF4. E sembra che io possa capito il problema .. mentre guardando l'oggetto di database .. lo stato della connessione è chiusa e la versione del server generano un'eccezione di questo genere:
ServerVersion = '(((System.Data.Entity.DbContext (_database)).Database.Connection).ServerVersion' threw an exception of type 'System.InvalidOperationException'
sto facendo le cose giuste? C'è qualcosa di sbagliato in ciò che è stato costruito?
Anche se si consiglia di conoscere il codice che ho pubblicato, sarei felice. Sto solo cercando di imparare il modo giusto per creare qualsiasi tipo di applicazione in MVC 3. Voglio iniziare bene.
io uso:
Entity Framework 4 con Codice-First
ASP.NET MVC 3
Ninject come DI Container
SQL Server Express (non R2)
Visual Studio 2010 Web Express
Grazie mille per il vostro aiuto!
Dove hai preso il picchiettio per questo con Entity ? Sono interessato a guardare qualcosa di simile. Ho visto alcuni modelli simili nell'applicazione Shrinkr scritta da Kazi Manzur Rashid @ http://shrinkr.codeplex.com/ –
Penso che questo codice sia stato originariamente da http://myfinance.codeplex.com/ – woggles
Nope ive riunito questo codice da altri post in questo posto più qualcuno con cui ho parlato che è davvero esperto nella zona. Era mia intenzione mettere qui tutto il mio codice per aiutare gli altri a darsi da fare. – Rushino