我已經在我的web應用程序中使用通用服務和存儲庫構建進行了分層設計。我想先使用代碼,這樣我就可以編寫我的實體,然後創建/更新我的數據庫。然而,我似乎無法得到它的工作。我不熟悉代碼第一個概念,生成數據庫並播種它,所以它可能很明顯;-)數據庫未更新使用存儲庫模式和EF代碼優先
我的應用程序設計如下。
- 網站
- Website.DAL
- Website.TESTS(尚未使用)
的website.DAL項目包含我的通用服務和存儲庫,以及DataContext的和我的實體。這個想法是,我可以在我的某個實體的控制器中實例化一個泛型的服務。該服務可以包含更多功能來執行計算等。而存儲庫僅用於處理CRUD操作。該網站項目的項目有一個參考Website.DAL項目,並且EF5也通過NuGet安裝在兩個項目中。
DataContext的是這樣的:
using System.Data.Entity;
using System.Web;
using Website.DAL.Entities;
namespace Website.DAL.Model
{
public class MyContext : DbContext
{
public IDbSet<Project> Projects { get; set; }
public IDbSet<Portfolio> Portfolios { get; set; }
/// <summary>
/// The constructor, we provide the connectionstring to be used to it's base class.
/// </summary>
public MyContext()
: base("MyConnectionstringName")
{
//MyContext.Database.Initialize(true);
//if (HttpContext.Current.IsDebuggingEnabled)
//{
// //Database.SetInitializer<MyContext>(new DatabaseInitializer());
// Database.SetInitializer<MyContext>(null);
//}
//else
//{
// //Database.SetInitializer<MyContext>(new CreateInitializer());
//}
}
static MyContext()
{
Database.SetInitializer<MyContext>(null);
}
/// <summary>
/// This method prevents the plurarization of table names
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();
}
//public void Seed(MyContextContext)
//{
// // Normal seeding goes here
// Context.SaveChanges();
//}
}
}
我還創建了一個DatabaseInitialiser類,這是目前空,但這個想法ofcourse是讓種子我的數據庫它創建或更新時。
的DatabaseInitialiser類看起來像這樣:
using System.Data.Entity;
using Website.DAL.Model;
namespace Website.DAL
{
public class DatabaseInitializer : DropCreateDatabaseIfModelChanges<MyContext>
{
public DatabaseInitializer()
{
}
protected override void Seed(MyContextcontext)
{
//TODO: Implement code to seed database
//Save all changes
context.SaveChanges();
}
}
}
由於GenericService是不相關的問題,我會離開它,因爲它是唯一currenlty製作到存儲庫中直接調用,沒有任何具體的業務情報。
使用的通用存儲庫看起來像這樣。這裏仍然需要改進,但現在起作用。
GenericRepository
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Website.DAL.Model;
using Website.DAL.RepositoryInterfaces;
namespace Website.DAL.Repositories
{
public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
#region Implementation of IRepository<TEntity>
//protected SceObjectContext DataContext;
//protected ObjectContext DataContext;
private MyContext _context;
//private IObjectSet<T> ObjectSet;
private DbSet<TEntity> _dbSet;
public GenericRepository()
{
//DataContext = SceObjectContext.Current;
//DataContext = new ObjectContext("dbConnection");
_context = new MyContext();
//ObjectSet = DataContext.CreateObjectSet<T>();
_dbSet = _context.Set<TEntity>();
}
/// <summary>
/// Inserts a new object into the database
/// </summary>
/// <param name="entity">The entity to insert</param>
public void Insert(TEntity entity)
{
//var entitySetName = GetEntitySetName(typeof(T));
//DataContext.AddObject(entitySetName, entity);
_dbSet.Add(entity);
}
/// <summary>
/// Deletes the specified entity from the database
/// </summary>
/// <param name="entity">The object to delete</param>
public void Delete(TEntity entity)
{
//DataContext.DeleteObject(entity);
if (_context.Entry(entity).State == System.Data.EntityState.Detached)
{
_dbSet.Attach(entity);
}
_dbSet.Remove(entity);
}
/// <summary>
/// Saves all pending chances to the database
/// </summary>
public void Save()
{
_context.SaveChanges();
}
/// <summary>
/// Retrieves the first object matching the specified query.
/// </summary>
/// <param name="where">The where condition to use</param>
/// <returns>The first matching object, null of none found</returns>
public TEntity First(Expression<Func<TEntity, bool>> @where)
{
return _dbSet.FirstOrDefault(where);
}
/// <summary>
/// Gets a list of all objects
/// </summary>
/// <returns>An strong typed list of objects</returns>
public IEnumerable<TEntity> GetAll()
{
return _dbSet.AsEnumerable<TEntity>();
}
/// <summary>
/// Returns ans iQueryable of the matching type
/// </summary>
/// <returns>iQueryable</returns>
public IQueryable<TEntity> AsQueryable()
{
return _dbSet.AsQueryable();
}
#endregion
}
}
我有我已經創建了兩個實體。投資組合是其中之一,顯示在下面。項目是第二個,它只是一個簡單的POCO類,有一個Id和一些屬性。
Portfolio.cs
public class Portfolio
{
[Key]
public Guid Id { get; set; }
public String Name { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool IsPublished { get; set; }
public virtual ICollection<Project> Projects { get; set; }
}
所有類以上保持在我的Website.DAL項目。我的網站項目中的Global.asax包含一些調用初始化程序的代碼,據我所知,應該確保在不久的將來可以完成播種並維護數據庫表。
的Global.asax
try
{
//Regenerate database if needed.
//Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>());
//Database.SetInitializer(new DatabaseInitializer());
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BorloContext>());
//Database.SetInitializer<MyContext>(new MigrateDatabaseToLatestVersion<MyContext>());
}
catch (Exception)
{
throw;
}
只是爲了它的緣故我已經得到了我的HomeController一段代碼,它應該得到的所有投資組合項目的ID。
var list = _portfolioService.GetAll();
在通過代碼進行調試時發生以下情況;
- Global.asax中的初始化代碼通行證。
- databaseinitialiser的構造函數調用
- homecontroller中的代碼不會引發異常。但是,在將手錶添加到'_portfolioService.GetAll()'的調用中時'我收到以下例外;
我也弄不清是怎麼回事錯在這裏。當然,例外情況不好,但我不能查看內部例外,因爲它沒有給我一個例外。我能做些什麼才能做到這一點?或者不是我想要實現的事情不可能,DAL層應該合併到網站中以使代碼生成工作?
更新1:
好吧,我已經改變了下面一行在我的上下文
Database.SetInitializer<MyContext>(null);
要
Database.SetInitializer<MyContext>(new DatabaseInitializer());
現在,我得到這個錯誤和堆棧跟蹤時調試'_portfolioService.GetAll();'調用HomeController的
錯誤:
Model compatibility cannot be checked because the database does not contain model metadata. Model compatibility can only be checked for databases created using Code First or Code First Migrations.
bij System.Data.Entity.Internal.ModelCompatibilityChecker.CompatibleWithModel(InternalContext internalContext, ModelHashCalculator modelHashCalculator, Boolean throwIfNoMetadata)
bij System.Data.Entity.Internal.InternalContext.CompatibleWithModel(Boolean throwIfNoMetadata)
bij System.Data.Entity.Database.CompatibleWithModel(Boolean throwIfNoMetadata)
bij System.Data.Entity.DropCreateDatabaseIfModelChanges`1.InitializeDatabase(TContext context)
bij System.Data.Entity.Database.<>c__DisplayClass2`1.<SetInitializerInternal>b__0(DbContext c)
bij System.Data.Entity.Internal.InternalContext.<>c__DisplayClass8.<PerformDatabaseInitialization>b__6()
bij System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
bij System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()
bij System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c)
bij System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input)
bij System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action)
bij System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
bij System.Data.Entity.Internal.InternalContext.Initialize()
bij System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
bij System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
bij System.Data.Entity.Internal.Linq.InternalSet`1.GetEnumerator()
bij System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator()
bij System.Linq.SystemCore_EnumerableDebugView`1.get_Items()
哈! 「**執行命令定義時發生錯誤... **」回答您的問題並不容易,至少不是非荷蘭語的用戶:)我不得不從您的屏幕截圖中輸入荷蘭語消息穀歌翻譯。消息中是否有一些有趣的內容?它截圖中的截圖... – Slauma
@Slauma,對不起。將翻譯錯誤和更新問題:) – Rob
@Slauma,請參閱更新1後的意見:) – Rob