我首先使用代码来建模数据库。我试图遵循几个不同的教程,并遇到所有这些问题,并且无法弄清楚原因。
现在我有一个新的MVC 4项目。我正在与另外3个人一起开展此项目,我们正在使用Team Foundation Server进行源代码管理。按照各种教程,我将我的模型设置为:
public class User
{
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public virtual ICollection<Entry> Entries { get; set; }
public virtual ICollection<Rating> Ratings { get; set; }
}
public class Contest
{
public int ContestId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public Boolean Published { get; set; }
public virtual ICollection<Submission> Submissions { get; set; }
public virtual ICollection<Tab> Tabs { get; set; }
}
public class Tab
{
public int TabId { get; set; }
public string Name { get; set; }
public int Order { get; set; }
public string Content { get; set; }
public int ContestId { get; set; }
public virtual Contest Contest { get; set; }
}
public class Entry
{
public int EntryId { get; set; }
public string Title { get; set; }
public string EmbedURL { get; set; }
public string Description { get; set; }
public Boolean isApproved { get; set; }
public int UserId { get; set; }
public virtual ICollection<Submission> Submissions { get; set; }
public virtual User User { get; set; }
}
public class Submission
{
public int SubmissionId { get; set; }
public DateTime Submitted { get; set; }
public int EntryId { get; set; }
public int ContestId { get; set; }
public virtual Entry Entry { get; set; }
public virtual Contest Contest { get; set; }
}
public class Rating
{
public int RatingId { get; set; }
public int Stars { get; set; }
public int UserId { get; set; }
public int SubmissionId { get; set; }
public virtual User User { get; set; }
public virtual Submission Submission { get; set; }
}
并创建了DbContext的扩展名:
public class CPContext : DbContext
{
public CPContext() : base("name=CPContext")
{
}
public DbSet<Contest> Contests { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<Entry> Entries { get; set; }
public DbSet<Submission> Submissions { get; set; }
public DbSet<Rating> Ratings { get; set; }
public DbSet<Tab> Tabs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
最后,我的Web.config文件中的连接字符串:
<add name="CPContext" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=aspnet_ContestPlatform;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
除此之外,我正在使用以下测试数据初始化我的数据库:
//Will seed the database with dummy values when accessed for first time
public class ContestPlatformInitializer : DropCreateDatabaseIfModelChanges<CPContext>
{
protected override void Seed(CPContext context)
{
var users = new List<User>
{
new User { FirstName = "Daniel", LastName = "Hines", Email = "hinesd@blah.edu" },
new User { FirstName = "Peter", LastName = "Pan", Email = "panp@blah.edu" },
new User { FirstName = "Marie", LastName = "VerMurlen", Email = "vermurle@blah.edu" },
new User { FirstName = "Aaron", LastName = "Brown", Email = "browna5@blah.edu" }
};
users.ForEach(s => context.Users.Add(s));
context.SaveChanges();
var entries = new List<Entry>
{
new Entry { UserId = 1, Title = "Flight Simulation", EmbedURL = "www.blah.com/video1", Description = "This is an awesome app!", isApproved = true },
new Entry { UserId = 2, Title = "Underwater Explorer", EmbedURL = "www.blah.com/video1", Description = "This is an awesome app!!", isApproved = true },
new Entry { UserId = 3, Title = "Dress-Up", EmbedURL = "www.blah.com/video1", Description = "This is an awesome app!!!", isApproved = true },
new Entry { UserId = 4, Title = "Combat Training", EmbedURL = "www.blah.com/video1", Description = "This is an awesome app!!!!", isApproved = true },
new Entry { UserId = 1, Title = "Fitness Pro", EmbedURL = "www.blah.com/video1", Description = "This is an awesome app!!!!!", isApproved = true }
};
entries.ForEach(s => context.Entries.Add(s));
context.SaveChanges();
var contests = new List<Contest>
{
new Contest { Name = "Game Contest", Description = "This contest is to see who can make the most awesome game!", Start = DateTime.Parse("2012-02-10"), End = DateTime.Parse("2012-04-20"), Published = true },
new Contest { Name = "App Contest", Description = "This contest is to see who can make the coolest app!", Start = DateTime.Parse("2012-03-10"), End = DateTime.Parse("2012-09-20"), Published = false }
};
contests.ForEach(s => context.Contests.Add(s));
context.SaveChanges();
var tabs = new List<Tab>
{
new Tab { ContestId = 1, Name = "Rules", Content = "The first rule is that there are no rules!", Order = 1 },
new Tab { ContestId = 2, Name = "Examples", Content = "No examples here yet, check back soon.", Order = 1}
};
tabs.ForEach(s => context.Tabs.Add(s));
context.SaveChanges();
var submissions = new List<Submission>
{
new Submission { ContestId = 1, EntryId = 1, Submitted = DateTime.Parse("2-13-2012") },
new Submission { ContestId = 1, EntryId = 2, Submitted = DateTime.Parse("2-14-2012") },
new Submission { ContestId = 1, EntryId = 3, Submitted = DateTime.Parse("2-15-2012") },
new Submission { ContestId = 1, EntryId = 4, Submitted = DateTime.Parse("2-16-2012") },
};
submissions.ForEach(s => context.Submissions.Add(s));
context.SaveChanges();
var ratings = new List<Rating>
{
new Rating { Stars = 4, UserId = 1, SubmissionId = 1 },
new Rating { Stars = 5, UserId = 2, SubmissionId = 1 },
new Rating { Stars = 2, UserId = 3, SubmissionId = 1 },
new Rating { Stars = 4, UserId = 4, SubmissionId = 1 },
new Rating { Stars = 1, UserId = 1, SubmissionId = 2 },
new Rating { Stars = 2, UserId = 2, SubmissionId = 2 },
new Rating { Stars = 1, UserId = 3, SubmissionId = 2 },
new Rating { Stars = 3, UserId = 4, SubmissionId = 2 },
new Rating { Stars = 5, UserId = 1, SubmissionId = 3 },
new Rating { Stars = 5, UserId = 2, SubmissionId = 3 },
new Rating { Stars = 4, UserId = 3, SubmissionId = 3 }
};
ratings.ForEach(s => context.Ratings.Add(s));
context.SaveChanges();
}
}
在我的Global.asax文件中的Application_Start()方法中调用。
现在为了测试一切正常,我为我的竞赛模型创建了一个控制器,它生成了一个相应的视图。当我编译我的应用程序并尝试调用Contest控制器时,会抛出异常。
System.Data.EntityCommandExecutionException未被用户代码处理 Message =执行命令定义时发生错误。有关详细信息,请参阅内部异常 来源= System.Data.Entity的 堆栈跟踪: 在System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand,CommandBehavior behavior) at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute [TResultType](ObjectContext context,ObjectParameterCollection parameterValues) 在System.Data.Objects.ObjectQuery
1.GetResults(Nullable
1 forMergeOption) 在System.Data.Objects.ObjectQuery1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at System.Collections.Generic.List
1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 source) at ContestPlatform.Controllers.ContestController.Index()在C:\ Users \ Danny \ Documents \ Visual Studio 2010 \ Projects \ ContestPlatform \ ContestPlatform \ ContestPlatform \ Controllers \ ContestController.cs:第21行 在lambda_method(Closure,ControllerBase,Object []) 在System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext,IDictionary`2参数) 在System.Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; c_ DisplayClass42.b _41() 在System.Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; c_ DisplayClass37。&lt;&gt; c _DisplayClass39.b_ 33() 在System.Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; c _DisplayClass4f.b__49() InnerException:System.Data.SqlClient.SqlException 消息=无效的对象名称'dbo.Contest'。 Source = .Net SqlClient数据提供程序 错误码= -2146232060 类= 16 LineNumber上= 1 数= 208 过程=“” 服务器=。\ SQLEXPRESS 状态= 1 堆栈跟踪: 在System.Data.SqlClient.SqlConnection.OnError(SqlException异常,布尔breakConnection) 在System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 在System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj) 在System.Data.SqlClient.SqlDataReader.ConsumeMetaData() 在System.Data.SqlClient.SqlDataReader.get_MetaData() 在System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,RunBehavior runBehavior,String resetOptionsString) 在System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,Boolean async) 在System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String method,DbAsyncResult result) 在System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String method) 在System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior,String method) 在System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior行为) 在System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand,CommandBehavior behavior) InnerException:
注意到“Message = Invalid object name'dbo.Contest'”这一行,我想仔细检查表dbo.Contest是否实际生成了。
我可以进入Management Studio Express并查看数据库“aspnet_ContestPlatform”,但它没有表格。
这是我应该看到的数据库吗?为什么没有生成表?此外,如果表不存在,为什么我的应用程序启动时没有得到异常,因为数据库应该被接种测试数据?
答案 0 :(得分:1)
不,数据库的名称应该是[YourNamespace,如果有的话] .CPContext,而不是“aspnet_ContestPlatform”。
我认为你没有立即获得异常的原因是因为只有当你点击使用实际执行你的GetResults的控制器的视图时它才会被它覆盖。有些事情阻止了数据库的创建 - 不确定是什么 - 但只要你不从中选择,应用程序中就没有任何失败。
您是否尝试过修改模型并再次运行应用程序?我经常在我的一个小实体上保留一个虚拟属性,我会交替评论开/关以重新生成数据库。我知道这不是最好的做事方式,但模型会发生变化,因此数据库应该删除并重新创建。