我知道SQL,但是我对ORM还是很陌生,可以在VS 2017中使用EntityFramework 6.2.0在沙箱中玩游戏。 我认为该框架应该使我能够像使用POCO对象一样或多或少地进行编码,而不必处理主键/外键。 我在下面的代码上下文中调用后,更改便立即保存在数据库中。 EF6及其文档我还不了解什么?
我使用外键和1:n关系创建了两个相互依赖的表Person和WorkingHours。
CREATE TABLE [dbo].[Person](
[FirstName] [nvarchar](100) NOT NULL,
[LastName] [nvarchar](100) NOT NULL,
[BirthDate] [date] NULL,
[Id] [int] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_Person] 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]
CREATE TABLE [dbo].[WorkingHours](
[Id] [int] NOT NULL,
[PersonId] [int] NOT NULL,
[Date] [date] NOT NULL,
[Start] [time](7) NOT NULL,
[Hours] [real] NOT NULL,
CONSTRAINT [PK_WorkingHours] 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]
我从数据库中创建了模型。
我尝试创建两个Person条目,每个条目都有一个WorkingHours条目,并将其立即保存到数据库中。 这是代码:
static void Main(string[] args)
{
using(var context = new EntityFrameworkTrialEntities2())
{
// Inserting entries
var person1 = new Person() { FirstName = "Al", LastName = "Curie", BirthDate = new DateTime(1867, 11, 7) };
var person2 = new Person() { FirstName = "Al", LastName = "Capone", BirthDate = new DateTime(1899, 1, 7) };
context.Person.Add(person1);
context.Person.Add(person2);
var workingHour1 = new WorkingHour() { Date = new DateTime(1887, 8, 18), Start = new TimeSpan(6, 35, 33), Hours = 4.3F };
var workingHour2 = new WorkingHour() { Date = new DateTime(1919, 9, 19), Start = new TimeSpan(10, 23, 56), Hours = 3.2F };
person2.WorkingHours.Add(workingHour1);
person1.WorkingHours.Add(workingHour2);
context.WorkingHours.Add(workingHour1);
context.WorkingHours.Add(workingHour2);
context.SaveChanges(); // <-- place of exeception !!!!!!!!!!!!!!!!!!!!
// (next step as EF6 trial: here the previously intentionally mixed relationships between person1/2 and workingHour2/1 shall be corrected)
但是在调用context.SaveChanges();时我收到此异常:
SqlException:违反了PRIMARY KEY约束'PK_WorkingHours'。无法在对象'dbo.WorkingHours'中插入重复的密钥。 重复的键值为(0)。 该声明已终止。**
我用更多的context.SaveChanges()和Attach()以及其他命令尝试了不同的方式,但是由于上述异常我总是失败。 默认将context.Configuration.ProxyCreationEnabled设置为true。
这里是模型类:
public partial class Person
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Person()
{
this.WorkingHours = new HashSet<WorkingHour>();
}
public string FirstName { get; set; }
public string LastName { get; set; }
public Nullable<System.DateTime> BirthDate { get; set; }
public int Id { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<WorkingHour> WorkingHours { get; set; }
}
public partial class WorkingHour
{
public int Id { get; set; }
public int PersonId { get; set; }
public System.DateTime Date { get; set; }
public System.TimeSpan Start { get; set; }
public float Hours { get; set; }
public virtual Person Person { get; set; }
}
答案 0 :(得分:2)
第一个问题是WorkingHour
的主键不是Identity Key
,因此始终将其设置为0
(默认值{{1 }}),每个int
都被复制。
因此,将WorkingHour
Id
的{{1}}列
第二个问题是以下几行:
WorkingHour
这里您要在上下文中添加两次[Id] [int] IDENTITY(1,1) NOT NULL
。一个带有person2.WorkingHours.Add(workingHour1); // adding with person
person1.WorkingHours.Add(workingHour2); // adding with person
context.WorkingHours.Add(workingHour1); // adding individually
context.WorkingHours.Add(workingHour2); // adding individually
实体,另一个带有单独实体。因此,删除第二组,只需按如下方式使用第一组即可:
WorkingHour
答案 1 :(得分:1)
我认为您的问题是由于[Id]
中的[WorkingHours]
:
CREATE TABLE [dbo].[WorkingHours](
[Id] [int] NOT NULL,
[PersonId] [int] NOT NULL,
[Date] [date] NOT NULL,
[Start] [time](7) NOT NULL,
[Hours] [real] NOT NULL,
CONSTRAINT [PK_WorkingHours] 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]
按如下所示进行更改,然后重试。
CREATE TABLE [dbo].[WorkingHours](
[Id] [int] IDENTITY(1,1) NOT NULL,
[PersonId] [int] NOT NULL,
[Date] [date] NOT NULL,
[Start] [time](7) NOT NULL,
[Hours] [real] NOT NULL,
CONSTRAINT [PK_WorkingHours] 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]