0

这篇文章已经过大量编辑和更新!

意图:

我正在编写一个本质上是一个迷你 ASP.NET MVC 3 会计包的应用程序。我这样做是为了学习 EF 4.1 Code First 和 Scaffolding

设置:

我正在使用带有 Mvc Scaffolding 1.0.2 的 SQL Server 2008 Express、Visual Studio 2010 SP1 和 ASP.NET MVC 3。

我有一个现有的数据库。该数据库具有以下表:

Accounts
Banks
CostCentres
Currencies
DebitCredits
People
Transactions
TransactionTypes

有许多关系,例如 Person_Accounts 等。

我现在想使用 MVC Scaffolding 创建一些输入页面,以便为我的数据库中的查找表创建数据。

我尝试了什么:

我创建了一个 .edmx 并使用它来使用 t4 自动生成创建 POCO 类。一旦我有了 POCO 课程,就排除了 .edmx。

已经解决了 EF 4.1 Code First 没有找到它喜欢的连接字符串的问题,所以开始创建自己的 sql express 数据库(有关此问题的详细信息,请参阅 Rachel Appels 博客

终于使用约定上下文名称 = 连接字符串名称首先获取 EF 代码以与正确的数据库对话。

然后我使用 MVC 3 Scaffolding 来搭建视图。所以生成的存储库代码不是我自己的,而是 Steve Sanderson 的。

我以前没有使用过 EF,所以希望这是一种通过“查看和学习”从 LINQ 发展到 SQL 的方式。

原来,我遇到了一些问题......

问题:

首先,如果我使用EF Code First创建的数据库,没有问题。

但是将连接字符串更改为我以前存在的数据库(我用来创建 .edmx 文件)我现在收到以下错误,例如,当我请求为 Accounts 实体搭建的索引视图时:

Invalid column name 'Account_AccountId'.
Invalid column name 'Account_AccountId'.
Invalid column name 'Currency_CurrencyId'.
Invalid column name 'Transaction_TransactionId'.
Invalid column name 'Account_AccountId1'.
Invalid column name 'Account_AccountId'.
Invalid column name 'Account1_AccountId'.
Invalid column name 'CostCentre_CostCentreId'.
Invalid column name 'Currency_CurrencyId'.
Invalid column name 'TransactionType_TransactionTypeId'.
Invalid column name 'Account_AccountId1'.
Invalid column name 'Account_AccountId2'.
Invalid column name 'Account_AccountId2'.
Invalid column name 'Account_AccountId'.
Invalid column name 'Account1_AccountId'.
Invalid column name 'CostCentre_CostCentreId'.
Invalid column name 'Currency_CurrencyId'.
Invalid column name 'TransactionType_TransactionTypeId'.
Invalid column name 'Account_AccountId1'.
Invalid column name 'Account_AccountId2'.

- 笔记: -

EF 创建的数据库和我创建的数据库(非常简单)之间的唯一区别是关系和几个触发器,以及一个 EdmMetadata 表。

--笔记结束--

我的推理:

乍一看,这个非常奇怪的错误的原因是,尽管只想要一个没有任何相关数据的帐户列表,但发生的情况如下:

使用我预先存在的数据库或首先由代码创建的数据库,当我签入 SQL Profiler 时,它会显示一个条目 SQL: BatchStarting,其中包含一个似乎正在选择数据库中几乎所有内容的大量 SELECT 查询。我不知道为什么调用这个庞大的查询而不是对事务数据的简单选择。据推测,它正在尝试加载所有相关数据,但我没有要求这样做。

再次强调,使用代码首先生成的数据库,一切正常。但是使用我预先存在的数据库,它会抛出上面显示的错误。

这里有两个问题:

  1. 一是错误。为什么会发生??

  2. 另一个是数据库中几乎所有数据的巨大选择语句!

我的观点只是试图吐出一个账户记录列表。我对 CostCentres 或 Currencies 表等(对于此视图)不感兴趣。

问题:

一个。为什么 Scaffolded 存储库要求提供所有数据?

湾。为什么在预先存在的数据库中发生错误?

我在这个问题上设置了赏金,谁回答了以上两个问题,谁就会得到赏金。

其他问题(与赏金无关!):

C。有谁知道博客的链接,我可以在其中阅读我应该如何使用 MVC 3 脚手架和代码首先与现有数据库一起使用?

d。有没有办法使用 t4 模板创建一个正确映射到现有数据库的 DbContext 文件,以及它的所有关系等?

e. 任何其他建议(不包括职业变化)​​?

F。有什么书可以阅读 EF 4.1 Code First 吗?(Julia Lerman 的最新版本是 EF 4.0,即 Code first 在发布时仅处于测试阶段)。

更新:

我已经回答了一个问题(为什么要引入所有数据的巨大查询。脚手架存储库有一个方法:

public IQueryable<Account> AllIncluding(params Expression<Func<Account, object>>[] includeProperties)
        {
            IQueryable<Account> query = context.Accounts;
            foreach (var includeProperty in includeProperties) {
                query = query.Include(includeProperty);
            }
            return query;
        }

从 Scaffolded 控制器调用:

//
        // GET: /Accounts/

        public ViewResult Index()
        {
            return View(accountRepository.AllIncluding(account => account.Person, account => account.DebitCredits, account => account.Transactions, account => account.Transactions1));
        }

我很抱歉。我太糊涂了。

但是问题 b 仍然没有答案。

4

1 回答 1

3

问题 b:您在预先存在的数据库列上收到错误的原因是它们与 codefirst 用来设置自己的关系以使用数据库的列命名约定不匹配,因为它存在您需要使用流利的映射或列属性在您的模型上定义关系应该是什么

对于代码优先 api 设置执行此操作的最佳方法不是使用 edmx 生成您的类,而是使用实体框架电动工具 ctp 来执行此操作

在生成它以学习流利的 api 及其工作原理后,我也会尝试在你的前几次手动执行此操作

因为您可以使用几种不同的模式

回答你关于引入所有数据的问题,它每次在编译时都会这样做一次,以创建数据库中所有内容的数据文件,然后跟踪它的更改以提高性能,因此它不必命中每次数据库

问题a:该AllIncluding功能允许您查询数据,如果您不想要,然后将其删除并替换为如何查询数据

问题d:

您可以编写自己的 t4 文件来生成您想要的任何代码,它们是模板并专门为此目的而设计

问题 f:

到目前为止,我还没有 4.1 的特定书籍,因为 codefirst 框架是全新的,我只在 4.0 版本中找到了一些,但是目前有 2 mvc 3 书籍我知道确实涵盖了 codefirst 的某些方面框架是专业的 asp.net mvc 3 (Wrox) 和 pro asp.net mvc 3 (apress),都可以在亚马逊上购买,每个大约 35-40 美元

于 2011-08-13T16:56:56.247 回答