Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何首先使用EF代码避免外部表中的重复行_C#_Sql Server_Entity Framework_Entity Framework 6 - Fatal编程技术网

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对象,然后使用返回的对象,而不是尝试重新使用预先创建的对象

正确的方法是,在第二个操作中,从context
context.Directors.FirstOrDefault(d=>d.Name==“A”)”
中找到director对象,并使用返回的对象,而不是试图重复使用你事先创建的。@尼克,你能把这个作为回答吗?按照你的要求做。有一个误解。这是一部新电影,由同一位导演执导,不是同一部电影的更新版
using (var context = new MovieContext())
{
    context.Movies.AddOrUpdate(m => m.Name, movie1);
    context.SaveChanges();
}