在我的应用程序中,Movies
存储在数据库中。这些Movies
有一个Name
和一个Director
。
众所周知,与其他人具有相同Name
的任何人都是同一个人。我想在应用程序中实现此约束。
我的模特是:
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; }
}
我的申请是
static void Main()
{
Director directorA = new Director()
{
Name = "A"
};
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();
}
}
(我将上下文放置在两个插入之间以模拟程序的两次不同运行)。
运行此命令会在Directors
表中创建两行:
Id Name
1 A
2 A
由于导演1和导演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引用的正确方法是什么?
答案 0 :(得分:1)
我认为您所描述的只是更新条目。如果已经使用特定名称创建了董事,并且使用相同名称创建了新董事,则应该限制创建,因为具有该名称的董事已经存在,但是如果表中包含“ email”之类的其他列,则该字段应更新,如果导演已经退出了吗?
如果是这种情况,为什么不只将Name作为表的主键?
<?php
require_once('sendgrid-php/sendgrid-php.php');
$name = $_POST["name"];
$email = $_POST["email"];
$header = $_POST["header"];
$message = $_POST["message"];
$from = new SendGrid\Email(null, $email);
$subject = $header;
$to = new SendGrid\Email(null, "MY EMAIL ADDRESS");
$content = new SendGrid\Content("text/plain", $message);
$mail = new SendGrid\Mail($from, $subject, $to, $content);
$apiKey = 'MY API KEY';
$sg = new \SendGrid($apiKey);
$response = $sg->client->mail()->send()->post($mail);
if($response->statusCode() == 202){
echo "Email sent successfully";
}else{
echo "Email could not be sent";
}
echo $response->statusCode();
var_dump($response->headers());
echo $response->body();
为什么有ID?
答案 1 :(得分:1)
正确的方法是,在第二个操作中,您将从上下文context.Directors.FirstOrDefault (d => d.Name == "A")
中找到导演对象并使用返回的对象,而不是尝试重新使用您事先创建的对象。
答案 2 :(得分:0)
然后您要首先将Director插入数据库。 insert语句将使用生成的ID更新内存中的模型,并且您插入的影片不会在数据库中创建新导演。
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();
}