实体框架(4.3)寻找单数名称而不是复数(当实体名称以“s”结尾)时 [英] Entity Framework (4.3) looking for singular name instead of plural (when entity name ends with "s")

查看:118
本文介绍了实体框架(4.3)寻找单数名称而不是复数(当实体名称以“s”结尾)时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的情况:
我一直在使用ASP.NET MVC 3应用程序一段时间。它有一个数据库(由数据库项目构建;我要去db-first),我有一个edmx模型,然后是一组POCO。我的实体在数据库中有多个名称,POCO有单数名称。一切都很好地映射没有问题。

Here's my situation: I have been working on an ASP.NET MVC 3 application for a while. It has a database (built out of a db project; I'm going db-first) for which I have an edmx model and then a set of POCOs. My entities have plural names in the database and POCOs have singular names. Everything maps nicely without a problem.

或用于直到我添加一个新表(称为TransactionStatuses)。现在所有的旧实体仍在工作,但新的没有。当我尝试与一个相关实体一起加载它:

Or used to until I added a new table (called TransactionStatuses). Now all of the old entities still work but the new one does not. When I try to eagerly load it together with a related entity:

var transactions = (from t in db.Transactions.Include(s => s.TransactionStatus) //TransactionStatus - navigation property in Transactions to TransactionStatuses
                    where t.CustomerID == CustomerID
                    select t).ToList();

我得到


无效的对象名称'dbo.TransactionStatus'。

Invalid object name 'dbo.TransactionStatus'.

我甚至做了一个更简单的测试:

I even did a simpler test:

List<TransactionStatus> statuses = db.TransactionStatuses.ToList();

=相同结果

更新(甚至重新创建)edmx从数据库,并已经通过它来回试图找出与dbo.TransactionStatus * es *的映射有什么不同之处。

I have updated (and even re-created) edmx from the db and have gone through it back and forth trying to figure out what is different about the mapping for dbo.TransactionStatus*es* which trips the whole thing up.

如果有人可以指出我的修复方向,这将是美好的。

If somebody can point me in the direction of a fix it'd be wonderful.

PS关闭多元化不是一个选择,谢谢。

P.S. Turning off pluralisation is not an option, thanks.

更新:我想到了 - 我的答案在下面。 >

Update: I figured it out - my answer below.

推荐答案

这可能是因为即使使用Database First流程,实际上应用程序正在使用Code First映射。让我多解释一点,因为这可能令人困惑。 : - )

This is probably happening because even though the intention was to use the Database First flow, in actual fact the application is using Code First to do the mapping. Let me explain a bit more because this can be confusing. :-)

当在Visual Studio中使用数据库优先与EF Designer和DbContext模板时,三个非常重要的事情发生。首先,新的实体数据模型向导将包含数据库优先模型(即EDMX)的详细信息的连接字符串添加到应用程序中,以便在应用程序运行时可以找到该模型。连接字符串将如下所示:

When using Database First with the EF Designer and the DbContext templates in Visual Studio three very important things happen. First, the new Entity Data Model wizard adds a connection string to your app containing details of the Database First model (i.e. the EDMX) so that when the application is run it can find this model. The connection string will look something like this:

<connectionStrings>
    <add name="MyEntities"
    connectionString="metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.\sqlexpress;initial catalog=MyEntities;integrated security=True;multipleactiveresultsets=True;App=EntityFramework&quot;"
    providerName="System.Data.EntityClient" />
</connectionStrings>

其次,生成的上下文类调用基础DbContext构造函数,指定此连接字符串的名称:

Second, the generated context class makes a call to the base DbContext constructor specifying the name of this connection string:

public MyEntities()
: base("name=MyEntities")
{
}

这告诉DbContext在配置中查找和使用MyEntities连接字符串。使用name =表示如果没有找到连接字符串,DbContext将会抛出 - 它不会只是按照惯例继续创建连接。

This tells DbContext to find and use the "MyEntities" connection string in the config. Using "name=" means that DbContext will throw if it doesn't find the connection string--it won't just go ahead and create a connection by convention.

如果要使用数据库优先,则必须使用与生成的连接字符串类似的连接字符串。具体来说,它必须包含模型数据(EDMX中的csdl,msl,ssdl),您必须确保DbContext找到它。更改对基础构造函数的调用时要非常小心。

If you want to use Database First, then you must use a connection string like the one that is generated. Specifically, it must contain the model data (the csdl, msl, ssdl from the EDMX) and you must make sure that DbContext finds it. Be very careful when changing the call to the base constructor.

发生的第三件事是,OnModelCreating在生成的上下文中被覆盖,并被抛出:

The third thing that happens is that OnModelCreating is overridden in the generated context and made to throw:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    throw new UnintentionalCodeFirstException();
}

这是因为OnModelCreating仅在使用Code First时被调用。这是因为OnModelCreating是关于创建模型,但是当您使用Database First时,模型已经存在 - 在运行时没有创建任何内容。所以如果OnModelCreating被调用,那么可能是因为你开始使用Code First而没有意义,通常是因为改变了连接字符串或者调用了基础构造函数。

This is done because OnModelCreating is only ever called when using Code First. This is because OnModelCreating is all about creating the model, but when you are using Database First the model already exists--there is nothing to create at runtime. So if OnModelCreating is called then it is probably because you started using Code First without meaning to, usually because of a change to the connection string or the call to the base constructor.

现在,您可能希望使用Code First映射到现有的数据库。这是一个很好的模式,完全支持(参见 http://blogs.msdn.com/b/adonet/archive/2011/03/07/when-is-code-first-not-code-first.aspx ),但是您需要确保映射适当设置,以使其正常工作。如果映射设置不正确,那么您将收到与此问题中的异常。

Now, it might be that you want to use Code First to map to an existing database. This is a great pattern and fully supported (see http://blogs.msdn.com/b/adonet/archive/2011/03/07/when-is-code-first-not-code-first.aspx) but you will need to make sure mappings are setup appropriately for this to work. If the mappings are not setup correctly then you will get exceptions like the one in this question.

这篇关于实体框架(4.3)寻找单数名称而不是复数(当实体名称以“s”结尾)时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆