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# 将虚拟集合形成到使用复合主键的表的实体框架_C#_Sql Server_Entity Framework_Entity Framework Core - Fatal编程技术网

C# 将虚拟集合形成到使用复合主键的表的实体框架

C# 将虚拟集合形成到使用复合主键的表的实体框架,c#,sql-server,entity-framework,entity-framework-core,C#,Sql Server,Entity Framework,Entity Framework Core,在实体框架中,如何将虚拟集合链接到另一个使用复合键的表?以下是两个示例表: 公共抽象类表1 { 公共Guid事件ID{get;set;} 公共字符串EventName{get;set;} 公共虚拟ICollection表2{get;private set;} } 及 公共抽象类表2 { 公共Guid事件ID{get;set;} 公共字符串DetailKey{get;set;} 公共字符串DetailValue{get;set;} 公共虚拟表1表1{get;set;} } 这意味着在表1中,添

在实体框架中,如何将虚拟集合链接到另一个使用复合键的表?以下是两个示例表:

公共抽象类表1
{
公共Guid事件ID{get;set;}
公共字符串EventName{get;set;}
公共虚拟ICollection表2{get;private set;}
}

公共抽象类表2
{
公共Guid事件ID{get;set;}
公共字符串DetailKey{get;set;}
公共字符串DetailValue{get;set;}
公共虚拟表1表1{get;set;}
}
这意味着在表1中,添加一个事件,然后使用一对多关系,将N行添加到表2中。在表1中,Guid
EventId
是主键,在表2中,主键由
EventId+DetailKey
组合而成,这意味着表2中可能有N行与表1中相应的
EventId
相关。表2的EventId的FK值也为
EventId

表1的映射文件如下(部分):

public override void ConfigureImp(EntityTypeBuilder)
{
基本配置导入(生成器);
//关系
builder.HasMany(t=>t.Table2)
.带一个(t=>t.Table1)
.HasForeignKey(x=>new{x.EventId,x.DetailKey});
}
表2的映射文件如下所示(部分):

public override void ConfigureImp(EntityTypeBuilder)
{
基本配置导入(生成器);
//关系
builder.HasOne(t=>t.Table1)
.WithMany(t=>t.Table2)
.HasForeignKey(x=>x.EventId)
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
}
让我们添加一些数据,比如在表1中添加一行EventId
FOO
,在表2中添加5行,其中表2中的每一行都有相同的EventId(满足FK),但有一个唯一的DetailKey(满足复合键)。完成此操作后,我运行如下查询:

Table1 target = db.Table1
                    .Include(x => x.Table2)
                    .SingleOrDefault(x => x.EventId.Equals("FOO"));
这样做之后,检查
目标的内容(比如,作为断点),我希望看到表1中的详细信息,以及表2中所有5行的详细信息,因为
。Include
。然而,我实际得到的只是表2中的一行,无论哪一行位于表中的第一行(这意味着它可以随着该
EventId
的其他行添加到表2中而改变)


关于我为什么不使用上面所示的
target
查询从表2中获取所有对应行的问题,有什么想法吗?谢谢。

不需要声明两次关系,外键就是EventId

乙二醇


公开课活动
{
公共Guid事件ID{get;set;}
公共字符串EventName{get;set;}
公共虚拟ICollection详细信息{get;private set;}
}
公共类事件详细信息
{
公共Guid事件ID{get;set;}
公共字符串DetailKey{get;set;}
公共字符串DetailValue{get;set;}
公共虚拟事件事件{get;set;}
}

模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasOne(t=>t.Event)
.有许多(t=>t.细节)
.HasForeignKey(x=>x.EventId)
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
modelBuilder.Entity().HasKey(e=>new{e.EventId,e.DetailKey});
基于模型创建(modelBuilder);
}

您只需添加必要的属性,就可以避免使用您编写的方法:

public  class Event
{
    [Key]
    public virtual Guid EventId { get; set; }
    public virtual string EventName { get; set; }
    public virtual ICollection<EventDetail> Details { get; set; }
}
public class EventDetail
{
    [Key, Column(Order = 0)]
    [ForeignKey("EventId")]
    public virtual Guid EventId { get; set; }
    [Key, Column(Order = 1)]
    public virtual string DetailKey { get; set; }
    public virtual string DetailValue { get; set; }
    public virtual Event Event{ get; set; }
}
公共类事件
{
[关键]
公共虚拟Guid事件ID{get;set;}
公共虚拟字符串EventName{get;set;}
公共虚拟ICollection详细信息{get;set;}
}
公共类事件详细信息
{
[键,列(顺序=0)]
[外键(“事件ID”)]
公共虚拟Guid事件ID{get;set;}
[键,列(顺序=1)]
公共虚拟字符串DetailKey{get;set;}
公共虚拟字符串DetailValue{get;set;}
公共虚拟事件事件{get;set;}
}

插入数据库的方法在哪里?“…获取的只是表2中的一行”你的意思是从数据库中,对吗?是的,从数据库中。为了这个示例,数据可以手动进入数据库。因此在
target
示例的末尾
db
是包含
Table1
Table2
模型的数据库上下文。两次声明它会导致这种类型的行为吗有连接的行又回来了?我对两边的逻辑是,除了上面的示例之外,我还可以提出这个样式请求:``Table2 target=db.Table2.Include(x=>x.Table1.SingleOrDefault(x=>x.Table1.EventId.Equals(“FOO”);```(喜欢反方向)谢谢你的回答,我只是想补充一点,我用更改过的键样式尝试了这一点,它的行为与以前相同(我从
Include
中得到了一行,而不是none,也不是all),所以我想肯定还有其他原因。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{


     modelBuilder.Entity<EventDetail>()
         .HasOne(t => t.Event)
         .WithMany(t => t.Details)
         .HasForeignKey(x => x.EventId)
         .OnDelete(DeleteBehavior.Restrict)
         .IsRequired();

    modelBuilder.Entity<EventDetail>().HasKey(e => new { e.EventId, e.DetailKey });

    base.OnModelCreating(modelBuilder);
}

public  class Event
{
    [Key]
    public virtual Guid EventId { get; set; }
    public virtual string EventName { get; set; }
    public virtual ICollection<EventDetail> Details { get; set; }
}
public class EventDetail
{
    [Key, Column(Order = 0)]
    [ForeignKey("EventId")]
    public virtual Guid EventId { get; set; }
    [Key, Column(Order = 1)]
    public virtual string DetailKey { get; set; }
    public virtual string DetailValue { get; set; }
    public virtual Event Event{ get; set; }
}