我通过在图像和项目实体上定义ICollection,使用EF CTP4中的默认约定创建了多对多的关系。
映射表创建如下:
create table [dbo].[Images_Project] (
[Images_Id] [uniqueidentifier] not null,
[Project_Id] [uniqueidentifier] not null,
primary key ([Images_Id]));
不幸的是,当我删除一个项目时,它并没有级联删除到图像映射表。
我希望EF能够在Imanges_Id和Project_Id属性上生成一个键,但事实并非如此。如何在删除项目时配置EF以删除图像映射? (只有图像映射记录,而不是图像记录)
由于
[更新]
虽然级联显然是不可能的,但任何想法都可以通过以下测试:
[Test]
public void Can_delete_project_with_images()
{
var project = new Project { Title = "Test project" };
var image = new Image { Title = "Some image" };
project.AddImage(image);
context.Set<Project>().Add(project);
context.SaveChanges();
object id = project.Id;
object imageId = image.Id;
var fromDb = context.Projects.Find(id);
fromDb.ShouldNotBeNull();
context.Set<Project>().Remove(fromDb);
context.SaveChanges();
var fromDb2 = context.Images.Find(imageId);
fromDb2.ShouldNotBeNull();
fromDb2.Title.ShouldEqual("Some image");
}
答案 0 :(得分:1)
从EF CTP4开始,没有办法直接在流畅的API中打开多对多关联的级联删除。唯一的方法是将链接表显式放入对象模型中:
public class Project
{
public int Id { get; set; }
public ICollection<ProjectXrefImage> Images { get; set; }
}
public class ProjectXrefImage
{
[Key][DataMember(Order = 1)]
public int ProjectId { get; set; }
[Key][DataMember(Order = 2)]
public int ImageId { get; set; }
public Project Project { get; set; }
public Image Image { get; set; }
}
public class Image
{
public int Id { get; set; }
public virtual ICollection<ProjectXrefImage> Projects { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Project> Projects { get; set; }
public DbSet<Image> Images { get; set; }
public DbSet<ProjectXrefImage> ProjectsXrefImages { get; set; }
}
那就是说,我个人不会这样做,并会在数据库中手动打开它们。
正如您通过测试用例发现的那样,代码首先会在客户端处理级联删除,即使它没有在数据存储上打开。这意味着,当您通过调用Remove()方法删除项目时,代码首先足够聪明,首先发送一个删除语句以从链接表中删除相关记录(Images_Projects),然后它将发送另一个删除语句到删除项目记录。我用SQL Profiler验证了这一点。
这就是为什么我们不能在多对多关系中打开级联删除,因为我们不需要它!我上面解释的惯例将为我们处理!
答案 1 :(得分:0)
SQL Server不允许您进行循环级联删除。