C# 实体框架查找错误的列

C# 实体框架查找错误的列,c#,asp.net,asp.net-mvc,vb.net,entity-framework,C#,Asp.net,Asp.net Mvc,Vb.net,Entity Framework,我对实体框架是全新的,并试图学习它所能提供的一切。我目前正在以我的方式通过,其中包括以下代码: public ActionResult Browse(string genre) { // Retrieve Genre and its Associated Albums from database var genreModel = storeDB.Genres.Include("Albums") .Single(g => g.Name == genre);

我对实体框架是全新的,并试图学习它所能提供的一切。我目前正在以我的方式通过,其中包括以下代码:

public ActionResult Browse(string genre)
 {
    // Retrieve Genre and its Associated Albums from database
    var genreModel = storeDB.Genres.Include("Albums")
        .Single(g => g.Name == genre);

    return View(genreModel);
 }
当我在VB中工作时,我将其转换为:

Function Browse(ByVal genre As String) As ActionResult

            'Retrieve Genre and its Associated Albums from database
            Dim genreModel = storeDB.Genres.Include("Albums"). _
                    Single(Function(g) g.Name = genre)

            Return(View(genreModel))
        End Function
问题是我遇到了以下异常:

列名“GenreGenreId”无效

我知道这是真的,但我一辈子都搞不清楚“GenreGenreId”是从哪里来的。可能是一个基本问题,但我会感谢任何在正确方向上的帮助


根据要求,这里是我的课程的来源:

Album.vb

Public Class Album

    Private _title As String
    Private _genre As Genre
    Private _AlbumId As Int32
    Private _GenreId As Int32
    Private _ArtistId As Int32
    Private _Price As Decimal
    Private _AlbumArtUrl As String

    Public Property Title As String
        Get
            Return _title
        End Get
        Set(ByVal value As String)
            _title = value
        End Set
    End Property

    Public Property AlbumId As Int16
        Get
            Return _AlbumId
        End Get
        Set(ByVal value As Int16)
            _AlbumId = value
        End Set
    End Property

    Public Property GenreId As Int16
        Get
            Return _GenreId
        End Get
        Set(ByVal value As Int16)
            _GenreId = value
        End Set
    End Property

    Public Property ArtistId As Int16
        Get
            Return _ArtistId
        End Get
        Set(ByVal value As Int16)
            _ArtistId = value
        End Set
    End Property

    Public Property AlbumArtUrl As String
        Get
            Return _AlbumArtUrl
        End Get
        Set(ByVal value As String)
            _AlbumArtUrl = value
        End Set
    End Property

    Public Property Price As Decimal
        Get
            Return _Price
        End Get
        Set(ByVal value As Decimal)
            _Price = value
        End Set
    End Property

    Public Property Genre As Genre
        Get
            Return _genre
        End Get
        Set(ByVal value As Genre)
            _genre = value
        End Set
    End Property


End Class
Genre.vb

Public Class Genre

    Dim _genreId As Int32
    Dim _Name As String
    Dim _Description As String
    Dim _Albums As List(Of Album)

    Public Property GenreId As Int32
        Get
            Return _genreId
        End Get
        Set(ByVal value As Int32)
            _genreId = value
        End Set
    End Property

    Public Property Name As String
        Get
            Return _Name
        End Get
        Set(ByVal value As String)
            _Name = value
        End Set
    End Property

    Public Property Description As String
        Get
            Return _Description
        End Get
        Set(ByVal value As String)
            _Description = value
        End Set
    End Property

    Public Property Albums As List(Of Album)
        Get
            Return _Albums
        End Get
        Set(ByVal value As List(Of Album))
            _Albums = value
        End Set
    End Property

End Class
MusicStoreEntities.vb

Imports System.Data.Entity

Namespace MvcApplication1

    Public Class MusicStoreEntities
        Inherits DbContext

        Public Property Albums As DbSet(Of Album)
        Public Property Genres As DbSet(Of Genre)

    End Class
End Namespace

genregreid
应该是
GenreId
,它是唱片集实体/唱片集表和流派实体/流派表中的一个字段。确保数据库设置正确。

请尝试重新创建模型文件。不应该有任何具有此名称的属性。

只是一个假设的解释:

MusicStore示例首先使用实体框架代码进行开发。而且它没有任何特殊的配置,既没有在模型类上使用代码优先属性,也没有使用fluentapi

这意味着EntityFramework完全根据一组约定推断数据库结构和所有关系,这些约定是在后台定义的,并且基于模型类的类和属性名

失败查询的重要类有(简化,仅相关属性):

公共类体裁
{
public int GenreId{get;set;}
公共字符串名称{get;set;}
公共列表相册{get;set;}
}
公开课相册
{
public int AlbumId{get;set;}
public int GenreId{get;set;}
公共虚拟类型{get;set;}
}
DbContext是:

public class MusicStoreEntities : DbContext
{
    public DbSet<Album> Albums { get; set; }
    public DbSet<Genre> Genres { get; set; }
    // other sets...         
}
公共类MusicStoreEntities:DbContext
{
公共数据库集相册{get;set;}
公共数据库集类型{get;set;}
//其他组。。。
}
现在,,由于
Album
类中的
Genre
属性和
Genre
类中的
Albums
集合,实体框架知道
Genre
Album
之间存在一对多关系,该关系作为外键关系映射到数据库中:
Albums
表必须具有
类型
表的外键。EF现在必须找出这个外键的名称,才能生成正确的SQL语句。我们的模型没有明确定义外键名称(这也是可能的),因此EF遵循一组约定,在本例中:

  • Album
    类是否具有名为

    [目标类的导航属性名称]+[目标类中主键属性名称的名称]

    在我们的例子中,这将是[Genre]+[GenreId]=
    GenreGenreId
    ->不,我们没有这样的属性

  • Album
    类是否具有名为

    [目标类的名称]+[目标类中主键属性名称的名称]

    在我们的例子中,这将是[Genre]+[GenreId]=
    GenreGenreId
    ->不,我们没有这样的属性

  • Album
    类是否具有名为

    [目标类中主键属性名称的名称]

    在我们的例子中,这将是[GenreId]=
    GenreId
    ->是的,我们在
    相册中有这样一个属性

因此,实体框架将假定
Album
类中的外键名为
GenreId
。与MVCMusicStore示例一起交付的DB中的数据库模式确实具有这样的列和外键关系

因此,我们的查询应该可以工作

但是如果我们从
Album
类中删除
public int-GenreId{get;set;}
,或者把它写错(“GenresId”或其他什么东西),会发生什么呢?上述三个约定规则都不适用,EF将假定我们的模型类没有表示关系外键的属性。但它仍然假设存在一种关系(因为导航属性)。要生成涉及此关系的SQL语句,EF必须采用数据库中外键列的任何名称。对于这个假设,它遵循上述三条规则中的第一条,因此它假设外键名为
genregreid
——但在数据库模式中,外键名为
GenreId
->

那么,最后一个问题:您正在运行的示例的
Album
类是否具有
GenreId
属性?(我已经看到MusicStore有几个示例步骤,但并非所有的
Album
都具有此属性。)

(如果它确实有这样的属性,那就忘了这篇文章。)

编辑


GenreId
中的
GenreId
Album
中的
GenreId
必须具有相同的类型,否则上述第三个约定规则不适用。在您的示例中,您有不同的类型(
Int16
Int32
)。这可能就是问题所在。

我也有一个类似的问题,这似乎是因为Album类有一个GenreID,而流派类有一个专辑列表。所以EF(我还不明白为什么)现在将开始在它为相册数据库集生成的查询中查找GenreGenreID列。如果您为流派创建的实体配置忽略了流派中的albums字段,那么这将“修复”该问题。或者,如果你在流派的albums属性中添加了一个ignore属性,它也会“修复”这个问题

选项1:

    public class GenreConfiguration : EntityTypeConfiguration<Genre>
    {
        public GenreConfiguration()
            : base()
        {
            HasKey(p => p.GenreId);
            Property(p => p.GenreId).
                HasColumnName("GenreId").
                HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).
                IsRequired();
            Property(p => p.Name).
                HasColumnName("Name").
                IsRequired();
            Ignore(p => p.Albums);
        }
    }
    public class Genre
    {
        public int GenreId { get; set; }
        public string Name { get; set; }

        [NotMapped]
        public List<Album> Albums { get; set; }
    }
公共类GenreConfiguration:EntityTypeConfiguration
{
公共资源重新配置()
:base()
{
HasKey(p=>p.GenreId);
属性(p=>p.GenreId)。
哈斯彭纳
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       modelBuilder.Configurations.Add<Genre>(new GenreConfiguration());
       modelBuilder.Entity<Genre>().ToTable("Genre");
    }
    public class Genre
    {
        public int GenreId { get; set; }
        public string Name { get; set; }

        [NotMapped]
        public List<Album> Albums { get; set; }
    }