实体框架5 - 0..1到多个关系无法保存新实体

时间:2013-03-25 19:39:54

标签: c# asp.net sql asp.net-mvc entity-framework

我正在使用ASP.NET MVC 4和Entity Framework 5.我使用模型第一种方法来生成数据库。在我的应用程序中,我有一个运行的日志表和一个鞋表。用户可以拥有与正在运行的日志条目相关联的0或1双鞋。所以这似乎是一个0..1到很多关系,这就是我在模型中设置它的方式。当我context.SaveChanges()添加一个没有任何鞋子的新条目时,我收到此错误:

The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_ShoeLogEntry\".

一旦我选择一双鞋作为日志条目,它就可以了。那么如何正确设置关系,以便日志条目可以为鞋子设置空值?我已粘贴在下面的代码中:

代码我用来添加新条目

le.ActivityType = ctx.ActivityTypes.Find(le.ActivityTypesId);
le.User = ctx.Users.Find(le.UserUserId);
le.Shoe = ctx.Shoes.Find(le.ShoeShoeId); //ShoeShoeId is null if nothing picked
ctx.LogEntries.Add(le);
ctx.SaveChanges();

我已经尝试检查ctx.Shoes.Find(le.ShoeShoeId)是否返回null并将le.Shoe设置为null而将le.ShoeShoeId设置为null-1并且没有'工作。

我尝试在下面粘贴相关代码,但这对我来说很新鲜。所以我可以在必要时添加更多。我真的很感激任何帮助!

外键设置

-- Creating foreign key on [ShoeShoeId] in table 'LogEntries'
ALTER TABLE [dbo].[LogEntries]
ADD CONSTRAINT [FK_ShoeLogEntry]
FOREIGN KEY ([ShoeShoeId])
REFERENCES [dbo].[Shoes]
    ([ShoeId])
ON DELETE NO ACTION ON UPDATE NO ACTION;

-- Creating non-clustered index for FOREIGN KEY 'FK_ShoeLogEntry'
CREATE INDEX [IX_FK_ShoeLogEntry]
ON [dbo].[LogEntries]
   ([ShoeShoeId]);
GO

主键设置

-- Creating primary key on [ShoeId] in table 'Shoes'
ALTER TABLE [dbo].[Shoes]
ADD CONSTRAINT [PK_Shoes]
   PRIMARY KEY CLUSTERED ([ShoeId] ASC);
GO

-- Creating primary key on [LogId] in table 'LogEntries'
ALTER TABLE [dbo].[LogEntries]
ADD CONSTRAINT [PK_LogEntries]
   PRIMARY KEY CLUSTERED ([LogId] ASC);
GO

由模型生成的日志条目类

public partial class LogEntry
{
    public int LogId { get; set; }
    public string ActivityName { get; set; }
    public System.DateTime StartTime { get; set; }
    public string TimeZone { get; set; }
    public int Duration { get; set; }
    public decimal Distance { get; set; }
    public Nullable<int> Calories { get; set; }
    public string Description { get; set; }
    public string Tags { get; set; }
    public int UserUserId { get; set; }
    public Nullable<int> ShoeShoeId { get; set; }
    public int ActivityTypesId { get; set; }

    public virtual User User { get; set; }
    public virtual Shoe Shoe { get; set; }
    public virtual ActivityTypes ActivityType { get; set; }
}

由模型生成的鞋类

public partial class Shoe
{
    public Shoe()
    {
        this.ShoeDistance = 0m;
        this.LogEntries = new HashSet<LogEntry>();
    }

    public int ShoeId { get; set; }
    public string ShoeName { get; set; }
    public decimal ShoeDistance { get; set; }
    public int ShoeUserId { get; set; }
    public string ShoeBrand { get; set; }
    public string ShoeModel { get; set; }
    public System.DateTime PurchaseDate { get; set; }
    public int UserUserId { get; set; }

    public virtual User User { get; set; }
    public virtual ICollection<LogEntry> LogEntries { get; set; }
}

1 个答案:

答案 0 :(得分:8)

如果你想要0到多,那么你的外键必须是可空的,即:

public int? ShoeId { get; set; }

正如你现在所知,你告诉EF ShoeId不能为空,所以你只有1到多。

修改

抱歉,我正在查看错误的课程,但我会将其留给可能需要它的其他人。但是,情况在这里仍然几乎相同。发生的事情是你没有遵循FK命名的EF约定(ShoeShoeId)。对于类似Shoe的虚拟广告,EF会查找属性ShoeId。如果找到一个,那将是FK字段,如果没有,EF将自动在数据库中添加一个Shoe_ShoeId字段用于FK。这个自动添加的字段将是不可为空的,这就是这里发生的事情。

如果你坚持你的FK为ShoeShoeId,请明确告诉EF这是Shoe的FK:

[ForeignKey("Shoe")]
public int? ShoeShoeId { get; set; }