实体框架(4.3)寻找奇异的名字,而不是复数(当实体名称与&QUOT结束; S")实体、复数、奇异、而不是

2023-09-04 01:54:41 作者:爱耍流氓的兔子

下面是我的情况: 我一直在做一个ASP.NET MVC 3应用程序一段时间。它有一个数据库(内置了一个数据库项目;我要去DB-优先),我有一个EDMX模型,然后一组波苏斯的。我的实体具有多个名称中的数据库和波苏斯具有奇异的名字。一切都很好地映射没有问题。

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();

=相同的结果。

= same result.

我已经更新(甚至重新创建)从DB 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.

P.S。关闭生成复数是不是一种选择,谢谢。的

更新:我理解了它 - 我的回答如下

Update: I figured it out - my answer below.

推荐答案

这是可能发生的,因为即使意图是使用数据库一是流通,实际上应用程序使用code首先要做的映射。让我解释一点,因为这可能会造成混淆。 : - )

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. :-)

在首先使用数据库的EF设计器和Visual Studio中的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找到并使用My​​Entities连接字符串中的配置。使用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.

如果你想使用数据库首先,​​你必须使用这样产生一个连接字符串。具体而言,它必须包含的模型数据(CSDL,MSL,从EDMX 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只用c首先$ C $当过调用。这是因为OnModelCreating是所有关于创建模型,但是当你使用的是数据库首先模型已经存在 - 没有要在运行时创建。因此,如果OnModelCreating叫那么它可能是因为你开始使用通常是因为更改了连接字符串或调用基构造函数code首先没有意义。

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.

现在,它可能是你想用$ C C首先$映射到现有的数据库。这是一个很好的模式,完全支持(请参阅http://blogs.msdn.com/b/adonet/archive/2011/03/07/when-is-$c$c-first-not-$c$c-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.