C# 如何首先使用EF代码避免外部表中的重复行
在我的应用程序中,C# 如何首先使用EF代码避免外部表中的重复行,c#,sql-server,entity-framework,entity-framework-6,C#,Sql Server,Entity Framework,Entity Framework 6,在我的应用程序中,电影存储在数据库中。这些电影有名称和导演 众所周知,任何与他人同名的人都是同一个人。我想在应用程序中实现这个约束 我的模型是: public class MovieContext: DbContext { public MovieContext(): base("name=testDB") { } public DbSet<Movie> Movies { get; set; } public DbSet<Director> Rev
电影
存储在数据库中。这些电影
有名称
和导演
众所周知,任何与他人同名的人都是同一个人。我想在应用程序中实现这个约束
我的模型是:
public class MovieContext: DbContext
{
public MovieContext(): base("name=testDB") { }
public DbSet<Movie> Movies { get; set; }
public DbSet<Director> Revenues { get; set; }
}
public class Movie
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual Director Director { get; set; }
}
public class Director
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
(我正在处理两个插入之间的上下文,以模拟程序的两次不同运行)
运行此命令将在控制器
表中创建两行:
Id Name
1 A
2 A
由于director 1和director 2的名称相同,所以他们是同一个人,因此我更希望有一行
我尝试对此使用索引,并修改了我的Director
模型:
public class Director
{
[Key]
public int Id { get; set; }
[Index(IsUnique =true), StringLength(30)]
public string Name { get; set; }
}
但是,这会在运行时抛出,因为EF会尝试插入同一行两次。这显然不是正确的做法
使用Entity Framework插入数据时,确保使用相同ID引用相同外来对象的正确方法是什么?我认为您所描述的只是更新一个条目。如果已使用特定名称创建了一个控制器,并且使用相同的名称创建了一个新的控制器,则应限制创建,因为已存在具有该名称的控制器,但如果表中有其他列,如“email”,则如果该控制器已退出,则应更新此字段 如果是这种情况,为什么不让Name作为表的主键呢
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string Name{ get; set; }
为什么有id?更新了答案
然后,首先要在DB中插入控制器。insert语句将使用生成的ID更新内存中的模型,并且电影插入不会在DB中创建新的导演
static void Main()
{
Director directorA = new Director()
{
Name = "A"
};
using (var context = new MovieContext())
{
context.Directors.Add(directorA);
context.SaveChanges(); // Here the object directorA will be updated with the right ID. So movie inserts wont create a new Director
}
Movie movie1 = new Movie()
{
Name = "foo",
Director = directorA
};
Movie movie2 = new Movie()
{
Name = "bar",
Director = directorA
};
using (var context = new MovieContext())
{
context.Movies.Add(movie1);
context.SaveChanges();
}
using (var context = new MovieContext())
{
context.Movies.Add(movie2);
context.SaveChanges();
}
}
您可以使用AddOrUpdate方法。第一个参数是用于检查唯一性的字段。因此,如果找到名称,现有条目将被更新,如果不存在,将插入新模型
using (var context = new MovieContext())
{
context.Movies.AddOrUpdate(m => m.Name, movie1);
context.SaveChanges();
}
正确的方法是,在第二个操作中,您可以从context
context.Directors.FirstOrDefault(d=>d.Name==“A”)
中找到director对象,然后使用返回的对象,而不是尝试重新使用预先创建的对象 正确的方法是,在第二个操作中,从contextcontext.Directors.FirstOrDefault(d=>d.Name==“A”)”
中找到director对象,并使用返回的对象,而不是试图重复使用你事先创建的。@尼克,你能把这个作为回答吗?按照你的要求做。有一个误解。这是一部新电影,由同一位导演执导,不是同一部电影的更新版
using (var context = new MovieContext())
{
context.Movies.AddOrUpdate(m => m.Name, movie1);
context.SaveChanges();
}