.net 多对多自引用表-guid Id本身会更改
我有一个参考的多对多表。它本身听起来很疯狂,所以这里有一张图片可以更好地了解这个问题 我使用guid作为主键和外键。 当我尝试将.net 多对多自引用表-guid Id本身会更改,.net,asp.net-core,entity-framework-core,asp.net-core-2.1,entity-framework-core-2.1,.net,Asp.net Core,Entity Framework Core,Asp.net Core 2.1,Entity Framework Core 2.1,我有一个参考的多对多表。它本身听起来很疯狂,所以这里有一张图片可以更好地了解这个问题 我使用guid作为主键和外键。 当我尝试将Foo的新实例添加到与数据库中的某个Foo有关系的数据库中时,以及在行myDbContext.Set().add(Foo)的确切时刻时,Guid将更改为 创建数据库的代码: internal class Foo { public Guid Id { get; set; } public string Title { get;
Foo
的新实例添加到与数据库中的某个Foo有关系的数据库中时,以及在行myDbContext.Set().add(Foo)的确切时刻传递代码>时,Guid将更改为
创建数据库的代码:
internal class Foo
{
public Guid Id { get; set; }
public string Title { get; set; }
public virtual List<DependencyFoo> Dependents { get; set; }
public virtual List<DependencyFoo> DependentsOf { get; set; }
}
internal class DependencyFoo
{
public virtual Foo Dependent { get; set; }
public Guid DependentId { get; set; }
public virtual Foo DependentOf { get; set; }
public Guid DependentOfId { get; set; }
}
internal class MyDbContext : DbContext
{
public DbSet<Foo> Foos { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=.\\SQLEXPRESS;Initial Catalog=fooDb;Trusted_Connection=True;Integrated Security=True");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<DependencyFoo>()
.HasKey(x => new { x.DependentOfId, x.DependentId });
modelBuilder.Entity<DependencyFoo>()
.HasOne(x => x.DependentOf)
.WithMany(x => x.DependentsOf)
.HasForeignKey(x => x.DependentOfId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<DependencyFoo>()
.HasOne(x => x.Dependent)
.WithMany(x => x.Dependents)
.HasForeignKey(x => x.DependentId);
}
}
内部类Foo
{
公共Guid Id{get;set;}
公共字符串标题{get;set;}
公共虚拟列表依赖项{get;set;}
{get;set;}的公共虚拟列表依赖项
}
内部类依赖项cyfoo
{
公共虚拟对象依赖{get;set;}
公共Guid DependentId{get;set;}
公共虚拟Foo依赖项{get;set;}
公共Guid DependentOfId{get;set;}
}
内部类MyDbContext:DbContext
{
公共DbSet Foos{get;set;}
配置时受保护的覆盖无效(DBContextOptions Builder Options Builder)
{
optionsBuilder.UseSqlServer(“数据源=。\\SQLEXPRESS;初始目录=fooDb;可信连接=True;集成安全=True”);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasKey(x=>new{x.DependentOfId,x.DependentId});
modelBuilder.Entity()
.HasOne(x=>x.DependentOf)
.WithMany(x=>x.DependentsOf)
.HasForeignKey(x=>x.DependentOfId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity()
.HasOne(x=>x.Dependent)
.具有多个(x=>x.依赖项)
.HasForeignKey(x=>x.DependentId);
}
}
实际测试:
internal class Program
{
private static void Main(string[] args)
{
MyDbContext myDbContext = new MyDbContext();
myDbContext.Set<Foo>().Add(new Foo { Title = "Some cool title" });
myDbContext.SaveChanges();
Foo fooDb = myDbContext.Set<Foo>().FirstOrDefault(x => x.Title == "Some cool title");
DependencyFoo dependencyFoo = new DependencyFoo
{
DependentOfId = fooDb.Id
};
Foo foo = new Foo
{
DependentsOf = new List<DependencyFoo>()
};
foo.DependentsOf.Add(dependencyFoo);
myDbContext.Set<Foo>().Add(foo);
}
}
内部类程序
{
私有静态void Main(字符串[]args)
{
MyDbContext MyDbContext=新的MyDbContext();
myDbContext.Set().Add(new Foo{Title=“Some cool Title”});
myDbContext.SaveChanges();
Foo fooDb=myDbContext.Set().FirstOrDefault(x=>x.Title==“一些很酷的标题”);
DependencyFoo DependencyFoo=新DependencyFoo
{
DependentOfId=fooDb.Id
};
Foo Foo=新Foo
{
DependentsOf=新列表()
};
foo.DependentsOf.Add(dependencyFoo);
myDbContext.Set().Add(foo);
}
}
知道为什么会这样吗?这和我的工作有关系吗
关系还是?PS(示例用foos:)简化)我认为问题在于映射Foo.Dependents DependencyFoo.Dependent
和Foo.DependentsOf DependencyFoo.dependentTof
foo
的实际依赖项/依赖项应该是(伪代码):
或者(效果是一样的,我只是觉得它更容易阅读和理解):
modelBuilder.Entity()
.HasMany(x=>x.Dependents)
.WithOne(x=>x.DependentOf)
.HasForeignKey(x=>x.DependentOfId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity()
.HasMany(x=>x.DependentsOf)
.WithOne(x=>x.Dependent)
.HasForeignKey(x=>x.DependentId);
这是否写在文档中的任何地方?我找不到太多用于自引用表的文档/文章,PS:我不需要进行迁移,这是为什么?没有。但这是合乎逻辑的。假设您有Person
和Children
集合,以及PersonLink
类和Parent
引用。然后关系是Person.Children PersonLink.Parent
和Person.Parents PersonLink.Child
您不需要迁移,因为交换集合导航属性不会更改链接表FKs。
IEnumerable<Foo> fooDependents = db.Set<DependencyFoo>()
.Where(d => d.DependentOf.Id == foo.Id)
.Select(d => d.Dependent);
IEnumerable<Foo> fooDependentsOf = db.Set<DependencyFoo>()
.Where(d => d.Dependent.Id == foo.Id)
.Select(d => d.DependentOf);
modelBuilder.Entity<DependencyFoo>()
.HasOne(x => x.DependentOf)
.WithMany(x => x.Dependents)
.HasForeignKey(x => x.DependentOfId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<DependencyFoo>()
.HasOne(x => x.Dependent)
.WithMany(x => x.DependentsOf)
.HasForeignKey(x => x.DependentId);
modelBuilder.Entity<Foo>()
.HasMany(x => x.Dependents)
.WithOne(x => x.DependentOf)
.HasForeignKey(x => x.DependentOfId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Foo>()
.HasMany(x => x.DependentsOf)
.WithOne(x => x.Dependent)
.HasForeignKey(x => x.DependentId);