EntityFramework:多个不规则名称的模型配置

时间:2013-10-13 20:36:28

标签: c# entity-framework asp.net-mvc-4 annotations linq-to-entities

我有一个用ASP.NET MVC4,EntityFramework Code First和Razor编写的系统。其中一个模型有以下声明:

public class Flour : IEntityBase
{
    [Key]
    public Guid FlourId { get; set; }
    public Guid ProcessId { get; set; }

    [Display(Name = "Timestamp", ResourceType = typeof(Resources.Language))]
    [Timestamp]
    public Byte[] Timestamp { get; set; }

    [Display(Name = "FlourAnalyzes", ResourceType = typeof(Resources.Language))]
    public virtual ICollection<FlourAnalysis> FlourAnalyzes { get; set; }
    [Display(Name = "Process", ResourceType = typeof(Resources.Language))]
    public virtual Process Process { get; set; }

    [Display(Name = "LastModified", ResourceType = typeof(Resources.Language))]
    public DateTime LastModified { get; set; }
    [Display(Name = "CreatedOn", ResourceType = typeof(Resources.Language))]
    public DateTime CreatedOn { get; set; }
}

如上所述,Flour的集合为FlourAnalysis。该模型描述如下:

[Table(name: "FlourAnalyzes")]
public class FlourAnalysis : IEntityBase
{
    [Key]
    public Guid FlourAnalysisId { get; set; }
    public Guid FlourId { get; set; }
    public Guid? MeshId { get; set; }

    [Display(Name = "Timestamp", ResourceType = typeof(Resources.Language))]
    [Timestamp]
    public Byte[] Timestamp { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd hh:mm}", ApplyFormatInEditMode = true)]
    [Display(Name = "StartTimestamp", ResourceType = typeof(Resources.Language))]
    public DateTime? StartTimestamp { get; set; }

    [Display(Name = "HumidityPercentage", ResourceType = typeof(Resources.Language))]
    [Range(0, 100)]
    public Double HumidityPercentage { get; set; }

    [Display(Name = "StarchPercentage", ResourceType = typeof(Resources.Language))]
    [Range(0, 100)]
    public Double StarchPercentage { get; set; }

    [DataType(DataType.MultilineText)]
    [Display(Name = "Comments", ResourceType = typeof(Resources.Language))]
    public String Comments { get; set; }

    [Display(Name = "Flour", ResourceType = typeof(Resources.Language))]
    public virtual Flour Flour { get; set; }
    [Display(Name = "Mesh", ResourceType = typeof(Resources.Language))]
    public virtual Mesh Mesh { get; set; }

    [Display(Name = "LastModified", ResourceType = typeof(Resources.Language))]
    public DateTime LastModified { get; set; }
    [Display(Name = "CreatedOn", ResourceType = typeof(Resources.Language))]
    public DateTime CreatedOn { get; set; }

    public FlourAnalysis() {
        this.HumidityPercentage = 0;
        this.StarchPercentage = 0;
    }

生成迁移后,EF创建了一个名为FlourAnalyzes的表(我需要强制使用表名,否则EF将以单数形式创建表)。在插入一些数据后,EF不会通过上下文调用FlourAnalysis数据来调用Flour个对象:

[Authorize]
public ViewResult Details(System.Guid id)
{
    var flour = context.Flours
        .Include(f => f.FlourAnalyzes)
        .Single(x => x.FlourId == id);

    return View(flour);
}

修改

在提出一些建议之后,我将.Single()表达式更改为.Where(),生成的SQL指向一个甚至不存在的列Flour_ProcessId

{SELECT 
[Project1].[C1] AS [C1], 
[Project1].[ProcessId] AS [ProcessId], 
[Project1].[FlourId] AS [FlourId], 
[Project1].[Timestamp] AS [Timestamp], 
[Project1].[LastModified] AS [LastModified], 
[Project1].[CreatedOn] AS [CreatedOn], 
[Project1].[Mesh_MeshId] AS [Mesh_MeshId], 
[Project1].[C2] AS [C2], 
[Project1].[FlourAnalysisId] AS [FlourAnalysisId], 
[Project1].[FlourId1] AS [FlourId1], 
[Project1].[MeshId] AS [MeshId], 
[Project1].[Timestamp1] AS [Timestamp1], 
[Project1].[StartTimestamp] AS [StartTimestamp], 
[Project1].[HumidityPercentage] AS [HumidityPercentage], 
[Project1].[StarchPercentage] AS [StarchPercentage], 
[Project1].[Comments] AS [Comments], 
[Project1].[LastModified1] AS [LastModified1], 
[Project1].[CreatedOn1] AS [CreatedOn1], 
[Project1].[Flour_ProcessId] AS [Flour_ProcessId]
FROM ( SELECT 
    [Extent1].[ProcessId] AS [ProcessId], 
    [Extent1].[FlourId] AS [FlourId], 
    [Extent1].[Timestamp] AS [Timestamp], 
    [Extent1].[LastModified] AS [LastModified], 
    [Extent1].[CreatedOn] AS [CreatedOn], 
    [Extent1].[Mesh_MeshId] AS [Mesh_MeshId], 
    1 AS [C1], 
    [Extent2].[FlourAnalysisId] AS [FlourAnalysisId], 
    [Extent2].[FlourId] AS [FlourId1], 
    [Extent2].[MeshId] AS [MeshId], 
    [Extent2].[Timestamp] AS [Timestamp1], 
    [Extent2].[StartTimestamp] AS [StartTimestamp], 
    [Extent2].[HumidityPercentage] AS [HumidityPercentage], 
    [Extent2].[StarchPercentage] AS [StarchPercentage], 
    [Extent2].[Comments] AS [Comments], 
    [Extent2].[LastModified] AS [LastModified1], 
    [Extent2].[CreatedOn] AS [CreatedOn1], 
    [Extent2].[Flour_ProcessId] AS [Flour_ProcessId], 
    CASE WHEN ([Extent2].[FlourAnalysisId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
    FROM  [dbo].[Flours] AS [Extent1]
    LEFT OUTER JOIN [dbo].[FlourAnalyzes] AS [Extent2] ON [Extent1].[ProcessId] = [Extent2].[Flour_ProcessId]
WHERE [Extent1].[FlourId] = @p__linq__0
)  AS [Project1]
ORDER BY [Project1].[ProcessId] ASC, [Project1].[C2] ASC}

我做错了什么?

2 个答案:

答案 0 :(得分:1)

为了避免您在Process_ProcessId时遇到的错误,您需要添加一个属性:

[ForeignKey("ProcessId")]
public virtual Process Process { get; set; }

这是因为用于生成外键的约定将使用错误的列名。

您可能还需要FlourAnalysis课程中的类似内容:

[ForeignKey("FlourId")]
public virtual Flour Flour { get; set; }

[ForeignKey("MeshId")]
public virtual Mesh Mesh { get; set; }

请注意,在所有情况下,我都忽略了代码中的其他属性,只是为了突出显示我添加的内容。

Here是一篇古老的文章,解释了您如何使用该属性。

有用提示,用于处理预先存在的数据库,以确定您是否正确定义了映射,是安装EF Power Tools并使用查看实体数据模型DDL SQL 选项,用于查看EF 认为数据库的内容。如果生成的SQL与您的实际数据库不匹配,则您需要修改模型注释或配置。

答案 1 :(得分:0)

默认情况下,实体框架将假设数据库中表的所有名称都是复数形式,或者在代码优先的情况下,您希望它们在创建时复数。

检查这希望它会有所帮助

http://edspencer.me.uk/2012/03/13/entity-framework-plural-and-singular-table-names/