我一直试图弄清楚实体框架核心的ASP.net核心在子实体方面是如何工作的。目前,我的问题是我可以创建一个“SomeThing”实体,将Status作为一个完整的实体,插入两者,但我无法弄清楚如何创建第二个“SomeThing”链接到相同的状态而不会抛出错误说它已经存在了?
以下是我的模型和上下文代码:
主要课程:
public class SomeThing
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int SomeThingId { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime? RequestedDate { get; set; }
[Required(ErrorMessage = "Description is required.")]
public string Description { get; set; }
[Required]
public int CreatedBy { get; set; }
public bool? Archived { get; set; }
//Linked items
[Required(ErrorMessage = "Status is required.")]
[ForeignKey("StatusCode")]
public Status Status { get; set; }
}
儿童班:
public class Status
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string Code { get; set; }
[Required(ErrorMessage = "The status requires a description")]
public string Description { get; set; }
public Status()
{
}
}
上下文:
public class OCWRContext : DbContext
{
public DbSet<Status> Statuses { get; set; }
public DbSet<SomeThing> WorkRequests { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<SomeThing>(entity =>
{
entity.HasKey(st => st.SomeThingId);
entity.Property<int>("SomeThingId")
.ValueGeneratedOnAdd();
entity.Property<byte[]>("Version")
.IsRowVersion();
entity.HasOne(st => st.Status)
.WithMany()
.OnDelete(DeleteBehavior.Restrict);
});
modelBuilder.Entity<Status>(entity =>
{
//entity.HasKey(s => s.Code);
//entity.HasMany(s => s.Code)
//.WithOne();
});
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySQL(connectionString);
}
}
我错误地链接了吗?在这个主题上我找不到对我有意义的东西。我来自一个主要的JS背景,之前从未使用过EF,所以我现在只是在圈子里跑。
我目前打电话来创建“SomeThing”是:
POST
{
"CreatedDate": "2018-06-14",
"Description": "There's a thing.",
"CreatedBy": 1,
"Archived": 0,
"Status": {
"Code": "1000",
"Description": "test"
}
}
让我再次朝着正确的方向前进的任何帮助都非常感谢!如果您需要我提供的任何其他信息,请告诉我们。我现在很想弄清楚这一点。
提前致谢,
史蒂夫
答案 0 :(得分:1)
如何创建第二个“SomeThing”链接到相同的状态,而不会抛出错误表明它已经存在
您遇到的问题称为Disconnected Entities
...有时使用一个上下文实例查询实体,然后使用其他实例保存。
...在这种情况下,第二个上下文实例需要知道实体是新的(应该插入)还是现有的(应该更新)。
在您的情况下,如果数据库已有Status
Code == "A"
,则您无法添加new Status
Code
。如果不改变你的背景或模型你可以做的事情是这样的:
Find
Status
,Code
Status
,则创建new Status
Status
设置为new SomeThing
上述步骤的示例代码:
using (var context = new OCWRContext())
{
string statusCode = "A";
Status status =
context.Statuses.Find(statusCode) //Step 1
?? context.Statuses.Add(new Status { Code = statusCode, Description = "" }).Entity; //Step 2
var someThing = new SomeThing
{
Status = status, //Step 3
Description = ""
};
context.Add(someThing);
context.SaveChanges();
}