【问题标题】:Entity Framework Error: The field "ForeignKey" is required EF实体框架错误:字段“ForeignKey”是必需的 EF
【发布时间】:2016-10-31 13:34:43
【问题描述】:

我有一个实体设置如下

public class ExampleObject
{
    [Key]
    public int ID { get; set; }
    public int RelationID { get; set; }
    public string SomeValue { get; set; }

    [ForeignKey("RelationID")]
    public virtual RelationObj RelationObj { get; set; }
}

后来在我的项目中,我使用这个实体如下

foreach (var rec in allRecs)
{
    db.ExampleObject.Attach(rec);
    rec.SomeValue = "TEST"
}

db.SaveChanges();

这会引发 DbEntityValidationException “需要字段“RelationObj””

我不想在加载这些记录时包含 RelationObj,这会影响性能。为什么 EF 费心检查外部关系对象?我该如何解决这个问题?

【问题讨论】:

  • 您需要指定EntityState。 db.Entry(rec).State = EntityState.Modified;通过这种方式,EF 将知道对象的属性已更改。
  • 这并不能解决根本问题。我懒惰地加载我的数据,当我需要做的只是更新一个简单的记录时,我不想“包含”每个相关的对象。
  • 阅读stackoverflow.com/questions/6038541/…。它将阐明您想做什么。
  • RelationObj 很可能为 null,因此 EF 必须将 RelationID 设置为 null,但由于此属性不可为 null,因此无法执行此操作。您必须为每个条目包含 RelationObj,因为 FK 不可为空。
  • RelationID 属性类型为 int。 EF 会将关系设置为必需。只需将属性RelationID 类型更改为int?

标签: c# .net entity-framework


【解决方案1】:

首先创建数据库,在脚本之上更改数据库以匹配您的数据库

USE [Breaz]
GO

/****** Object:  Table [dbo].[Relation]    Script Date: 6/29/2016 4:35:32 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Relation](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [RelatedSomeValue] [varchar](10) NULL,
 CONSTRAINT [PK_Relation] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

然后创建下一张表,再次更改数据库(Breaz):

USE [Breaz]
GO

/****** Object:  Table [dbo].[Example]    Script Date: 6/29/2016 4:34:15 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Example](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [RelationID] [int] NOT NULL,
    [SomeValue] [varchar](10) NULL,
 CONSTRAINT [PK_Example] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Example]  WITH CHECK ADD  CONSTRAINT [FK_Example_Relation] FOREIGN KEY([RelationID])
REFERENCES [dbo].[Relation] ([ID])
GO

ALTER TABLE [dbo].[Example] CHECK CONSTRAINT [FK_Example_Relation]
GO

在每个表中添加几行数据。

从您的数据库中添加新项目 ADO.NET 实体数据模型并添加两个表。命名 edmx ExampleModel。从 Example.Context.cs 文件中获取 (BreazEntities7) 上下文(您的上下文)。

 public class HomeController : Controller
{
    public ActionResult YIndex()
    {
        using (BreazEntities7 db = new BreazEntities7())
        {
            var allRecs = db.Examples;
            foreach (var rec in allRecs)
            {
                rec.SomeValue = "TEST";
            }
            db.SaveChanges();
        }
        return View();
}

这是生成的示例:

namespace Testy2.Models
{
    using System;
    using System.Collections.Generic;

    public partial class Example
    {
        public int ID { get; set; }
        public int RelationID { get; set; }
        public string SomeValue { get; set; }

        public virtual Relation Relation { get; set; }
    }
}

这里是生成的关系:

namespace Testy2.Models
{
    using System;
    using System.Collections.Generic;

    public partial class Relation
    {
        public Relation()
        {
            this.Examples = new HashSet<Example>();
        }

        public int ID { get; set; }
        public string RelatedSomeValue { get; set; }

        public virtual ICollection<Example> Examples { get; set; }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多