C# 实体框架(4.3)寻找单数名称而不是复数名称(当实体名称以“s”结尾时)

C# 实体框架(4.3)寻找单数名称而不是复数名称(当实体名称以“s”结尾时),c#,.net,entity-framework,entity-framework-4,entity-framework-4.3,C#,.net,Entity Framework,Entity Framework 4,Entity Framework 4.3,我的情况如下: 我已经在一个ASP.NETMVC3应用程序上工作了一段时间。它有一个数据库(由db项目构建;我先去db),我有一个edmx模型,然后是一组POCO。我的实体在数据库中有复数名称,POCO有单数名称。一切都映射得很好,没有问题 或者一直使用,直到我添加了一个新表(称为TransactionStatus)。现在所有的旧实体仍然可以工作,但新实体不能。当我尝试将其与相关实体一起加载时: var transactions = (from t in db.Transactions.Incl

我的情况如下: 我已经在一个ASP.NETMVC3应用程序上工作了一段时间。它有一个数据库(由db项目构建;我先去db),我有一个edmx模型,然后是一组POCO。我的实体在数据库中有复数名称,POCO有单数名称。一切都映射得很好,没有问题

或者一直使用,直到我添加了一个新表(称为TransactionStatus)。现在所有的旧实体仍然可以工作,但新实体不能。当我尝试将其与相关实体一起加载时:

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”无效

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

List<TransactionStatus> statuses = db.TransactionStatuses.ToList();
List status=db.transactionstatus.ToList();
=相同的结果

我已经从db中更新(甚至重新创建)了edmx,并反复查看它,试图找出dbo.TransactionStatus*es*映射的不同之处,这会让整个事情变得一团糟

如果有人能给我指出解决问题的方向,那就太好了

p.S.关闭多元化不是一个选项,谢谢


更新:我想出来了-下面是我的答案。

你提到了EDMX,但我不知道你是先用EDMX做数据库,还是先用代码,然后用EDMX看看发生了什么

如果先使用代码,则可以使用配置指定表名。数据注释为[Table(“TransactionStatus”)],fluent为modelBuilder.Entity().ToTable(“TransactionStatus”)。 (我正在从内存中输入注释和流畅的代码,以便仔细检查引用。)

如果您首先使用数据库,SSDL应该绝对知道数据库表的名称,因此我猜您首先使用的是代码&edmx只是为了探索。(?)

明白了! 可怕的,可怕的经历

简而言之:EF无法正确地将以“s”结尾的实体名称复数化。(例如,“状态”、“校园”等)

这是我如何得到它和证据的

  • 我已经多次创建并重新创建了我的原始设置,结果都是一样的
  • 我还尝试将我的表重命名为
    TransStatus
    之类的东西-没有运气
  • 当我研究这个问题的时候,我遇到了一个问题,他为单词添加了复数规则,比如
    sheep
    goose
    。这让我想到“如果问题出在实体的实际名称上怎么办?”
  • 我特别搜索了一下
    status
    这个词,找到了。我急忙尝试重命名我的实体
  • transactionstatus
    重命名为
    TransactionStates
    (同时将列保留为
    StatusID
    修复了该问题!我现在可以获得
    List status=db.TransactionStates.ToList()
  • 我想问题出在名字中的特定单词
    status
    。。。但在向一位朋友口头抱怨这件事之后,有人建议我,也许问题出在以“s”结尾的单词上。。。所以我决定去看看
  • 我设置了另一个名为
    Campuses
    的表和匹配的POCO
    Campus
    (并更新了edmx)。做了简单的测试
    List test=db.Campuses.ToList()并获得了现在期望的结果
无效的对象名称“dbo.Campus”


好了,强大的EF无法处理以“s”结尾的单词的复数形式。希望下一个遇到问题的可怜虫能找到这个问题,并为他或她自己节省3-4个小时的痛苦和挫折。

这很可能是因为即使目的是先使用数据库流,实际上应用程序还是先使用代码来做映射。让我再解释一下,因为这可能会让人困惑。:-)

在VisualStudio中首先使用数据库和EF设计器以及DbContext模板时,会发生三件非常重要的事情。首先,“新建实体数据模型向导”将向应用程序添加一个连接字符串,其中包含数据库第一个模型(即EDMX)的详细信息,以便在运行应用程序时可以找到此模型。连接字符串将如下所示:

<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在配置中查找并使用“MyEntities”连接字符串。使用“name=”意味着如果DbContext找不到连接字符串,它将抛出——它不会继续按照约定创建连接

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

发生的第三件事是OnModelCreating在生成的上下文中被重写,并被设置为抛出:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    throw new UnintentionalCodeFirstException();
}
之所以这样做,是因为OnModelCreating只有在第一次使用代码时才被调用。这是因为OnModelCreating是关于创建模型的,但是当您首先使用数据库时,模型已经存在了——在运行时没有什么可以创建的。因此,如果调用OnModelCreating,则可能是因为您首先开始使用代码而没有任何意义,通常是因为更改了连接字符串或调用了基本构造函数


现在,您可能希望首先使用代码映射到现有数据库。这是一个很好的模式,并且完全受支持(请参阅),但您需要确保映射设置正确,才能正常工作。如果映射设置不正确,则会出现与此问题类似的异常。

。同一类型的问题与班级和模型的照片和视频;它正在找桌子上的照片和录像带。我不喜欢只更改表名,但它看起来没有太多选择。

您能创建一个新的事务实例吗
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    throw new UnintentionalCodeFirstException();
}