【问题标题】:Wrong query generated with entity framework使用实体框架生成的错误查询
【发布时间】:2011-11-01 08:01:08
【问题描述】:

我需要知道我做错了什么,因为生成的查询与数据库表的属性不匹配,而且我认为我的类的类型和映射都很好。这是我的代码

public class Usuario
{
    #region Atributos
    private int _intID = 0;
    private Perfil _Perfil_FK = null;
    private String _strNombre = "";
    private String _strPassword = "";
    #endregion

    #region Propiedades

    public int ID
    {
        get { return _intID; }
        set { _intID = value; }
    }

    public Nullable<int> IDPerfil_FK { get; set; }

    public virtual Perfil Perfil_FK
    {
        get { return _Perfil_FK; }
        set { _Perfil_FK = value; }
    }
    public String Nombre
    {
        get { return _strNombre; }
        set { _strNombre = value; }
    }
    public String Password
    {
        get { return _strPassword; }
        set { _strPassword = value; }
    }
    #endregion
}

我的测试只是这个_db.Usuario()

生成的 Sql 查询

SELECT 
[Extent1].[IDUsuario] AS [IDUsuario], 
[Extent1].[IDPerfil_FK] AS [IDPerfil_FK], 
[Extent1].[Nombre] AS [Nombre], 
[Extent1].[Password] AS [Password], 
[Extent1].[PerfilID] AS [PerfilID] <-- this attribute doesn't exit's
FROM [dbo].[Usuario] AS [Extent1];

这是我的数据库上下文类

public class MasterPageAtentoDB : DbContext
{
    public DbSet<Pagina> Pagina { get; set; }
    public DbSet<Perfil> Perfil { get; set; }
    public DbSet<Permiso> Permiso { get; set; }
    public DbSet<Usuario> Usuario { get; set; }

    protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Usuario>().Property(r => r.ID).HasColumnName("IDUsuario");
        modelBuilder.Entity<Pagina>().Property(r => r.ID).HasColumnName("IDPagina");
        modelBuilder.Entity<Permiso>().Property(r => r.ID).HasColumnName("IDPermiso");
        modelBuilder.Entity<Perfil>().Property(r => r.ID).HasColumnName("IDPerfil");
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        base.OnModelCreating(modelBuilder);
    }
}

我的数据库表

【问题讨论】:

  • 我不确定,但 EF4.1 DbContext 的东西很大程度上基于名称和名称模式,我建议删除 _FK 后缀。

标签: c# linq entity-framework-4.1


【解决方案1】:

Entity Framework 无法将您的属性 IDPerfil_FK 识别为 Perfil_FK 导航属性的外键属性,因为您没有遵循自动 FK 属性检测所需的命名约定。因此,EF 假定 IDPerfil_FK 是一个普通的标量属性,并且 Perfil_FK 在您的模型中没有公开的 FK 属性,并且数据库中的列具有标准名称 Perfil_ID(导航属性名称 + “_” + 主要目标实体类的键属性名)。

您可以通过三个选项来解决此问题:

  • 适当命名FK属性(导航属性名称+目标实体类的主键属性名称):

    public Nullable<int> Perfil_FKID { get; set; }
    
  • 在属性上放一个数据注解属性,表示它是一个外键属性:

    [ForeignKey("Perfil_FK")]
    public Nullable<int> IDPerfil_FK { get; set; }
    
  • 在 Fluent API 中定义 FK 属性:

    modelBuilder.Entity<Usuario>()
        .HasOptional(u => u.Perfil_FK)
        .WithMany() // or with parameter if Perfil class refers back to Usuario
        .HasForeignKey(u => u.IDPerfil_FK);
    

我更喜欢第一个选项,因为您的主键属性映射无论如何都依赖于约定,因此也需要遵循外键属性的约定。

【讨论】:

    【解决方案2】:

    我相信您可以像添加数据注释一样简单地解决此问题,以提醒您的主键。

     [Key]
     public int ID
    

    默认情况下,EF 会尝试匹配 ClassnameId 作为 key,如果没有找到它会尝试匹配 Id 作为 key,否则会抛出错误。它区分大小写。因此,如果您想使用大写 ID,您需要使用 [Key] 注释显式标记它,以便它知道如何映射它。

    http://msdn.microsoft.com/en-us/data/gg193958 一些常用的注解。

    【讨论】:

      猜你喜欢
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      • 2012-06-21
      • 2014-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-28
      相关资源
      最近更新 更多