实体框架一对一关系

时间:2017-10-03 15:09:38

标签: c# entity-framework entity-framework-core

我在理解如何使用Entity Framework Core为Web API建立一对一关系属性时遇到一些问题。

考虑以下对象:

public class Car
{  
    [JsonIgnore]
    public Int32 CarId { get; set; }

    public virtual Horn Horn { get; set; }
    public virtual ICollection<Wheel> Wheels { get; set; }
}

public class Horn
{
    [JsonIgnore]
    public Int32 HornId { get; set; }
    public Sound Sound { get; set; }
}

public class Sound
{
    // some other props
}

当我在我的存储库中执行查询时,默认情况下会排除一对多,除非我使用.Include(),但是,对于一对一属性,我在序列化时默认包含它们。

e.g。它变得非常混乱,因为我查询汽车并返回JSON响应中的所有子组件。

我可以设置car.Horn = null等,但这似乎很难维护复杂的对象。我希望它的功能类似.Include(),但默认情况下会被排除(如果我想查询完整的对象)。

编辑:注意,这个问题是递归的,汽车拉入喇叭,拉入声音。在像用户表这样的现实世界示例中,序列化时自动提取的数据非常大,除非特别取消子属性。

EDIT2:

以下是存储库调用的示例,默认情况下会返回所有一对一属性:

var group = _context.Car.Include(c => c.Wheels).SingleOrDefault(u => u.CarId == id);

请注意,Include按预期方式进行多对一工作,但即使删除了Include,此查询也将以递归方式返回所有一对一的子对象。

在EF CORE 2.1

中出现了一些类型的延迟加载

2 个答案:

答案 0 :(得分:1)

这篇文章应该给你一个提示。 https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx 主要是:

  

关闭延迟加载以进行序列化

     

延迟加载和序列化不能很好地混合,如果不是这样的话   小心你最后只能因为查询整个数据库   延迟加载已启用。大多数序列化程序都可以通过访   类型实例上的属性。属性访问触发了懒惰   加载,因此更多实体被序列化。在那些实体属性上   被访问,甚至更多的实体被加载。这是一个很好的做法   在序列化实体之前关闭延迟加载。下列   部分显示了如何执行此操作。

编辑: 以下是禁用所有实体的延迟加载的方法。但请注意,您必须通过多种方式实现此目的,因此请查看文章中的其他选项...

public class YourContext : DbContext 
{ 
    public YourContext() 
    { 
        this.Configuration.LazyLoadingEnabled = false; 
    } 
}

答案 1 :(得分:0)

上下文映射

   modelBuilder.Entity<SessionFeedbackModel>(entity =>
        {
            entity.HasOne(s => s.Session).WithOne(p => p.Feedback)
                .HasForeignKey<SessionFeedbackModel>(s => s.SessionId).OnDelete(DeleteBehavior.Restrict);
        });

        modelBuilder.Entity<SessionQuestionModel>(entity =>
        {
            entity.HasOne(e => e.SessionResult).WithOne(e => e.SessionQuestion)
                .HasForeignKey<SessionQuestionResultModel>(e => e.SessionQuestionId)
                .OnDelete(DeleteBehavior.Restrict);

        });

模型

   public class SessionQuestionResultModel
    {
        public int Id { get; set; }

        public int SessionQuestionId { get; set; }

        public SessionQuestionModel SessionQuestion { get; set; }
    }


    public class SessionFeedbackModel
    {
        public int Id { get; set; }
        public int SessionId { get; set; }

        public SessionModel Session { get; set; }

    }

EF Core 1.x或2.x不能很好地支持1对1,或者根本不支持1对1,但它可以通过这种方式完成,对于EF 6.x.x来说,这将完全不同