EF实体间多对多的关系

添加一个活动类Activity,跟旅行类Trip是多对多的关系。这个也不难理解:一个旅行有多个活动,一个活动可以属于多个旅行。

复制代码
    /// <summary>
    /// 活动类
    /// </summary>
    public class Activity
    {
        public int ActivityId { get; set; }
        //[Required, MaxLength(50)]
        public string Name { get; set; }

        public List<Trip> Trips { get; set; }    //和Trip类是多对多关系
    }
复制代码

跟之前的一样在BreakAwayContext类里添加Activity类,让数据库上下文知道Activity类:

public DbSet<CodeFirst.Model.Activity> Activitys { get; set; }

同时在Trip旅行类里添加上导航属性,形成跟Activity活动类的多对多关系

 public List<Activity> Activitys { get; set; }

ok,已经可以了,跑下程序得到如下数据库:

可以看出,EF里的多对多关系是由第三张表来连接两个表的。ActivityTrips表连接了Activityes表和Trips表。表名列名都是默认命名,都可以自己配置。文章的开头已经说了那么多了,多对多肯定是用HasMany和WithMany方法,在ActivityMap类里写下如下Fluent API:

复制代码
            this.HasMany(a => a.Trips).WithMany(t => t.Activitys).Map(m =>
                {
                    m.ToTable("TripActivities");      //中间关系表表名
                    m.MapLeftKey("ActivityId");        //设置Activity表在中间表主键名
                    m.MapRightKey("TripIdentifier");   //设置Trip表在中间表主键名
                });
复制代码

同样也可以在TripMap里配置,顺序不一样罢了:

复制代码
            this.HasMany(t => t.Activities).WithMany(a => a.Trips).Map(m =>
            {
                m.ToTable("TripActivities");    //中间关系表表名
                m.MapLeftKey("TripIdentifier");   //设置Activity表在中间表的主键名
                m.MapRightKey("ActivityId");    //设置Trip表在中间表的主键名
            });
复制代码

两种配置任选其一就可以了,重新跑下程序就可以了。都配置好了在程序里如何读取这个对多对的数据呢,简单写一句:

var tripWithActivities = context.Trips.Include("Activities").FirstOrDefault();
 
 
是不是也需要考虑性能的问题呢?如果只需要修改主表的某个列,那贪婪加载出相关联的从表数据做什么?会发送很多冗余的sql到数据库。当然如果要根据主表找从表数据的话,这么加载也是好事,超级方便。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EF 中,我们可以使用导航属性来实现一对多关系的添加。假设我们有两个实体类,一个是主表实体类 `Parent`,另一个是从表实体类 `Child`,它们的关系是一个父亲可以有多个孩子,而每个孩子只有一个父亲。 首先,我们需要在 `Parent` 类中添加一个导航属性,表示这个主表实体类与从表实体类的关系: ```csharp public class Parent { public int Id { get; set; } public string Name { get; set; } public ICollection<Child> Children { get; set; } } ``` 在这个代码中,我们使用了 `ICollection<Child>` 类型的属性 `Children`,表示一个父亲可以有多个孩子。 然后,在 `Child` 类中,我们需要添加一个外键,来指向主表实体类的主键: ```csharp public class Child { public int Id { get; set; } public string Name { get; set; } public int ParentId { get; set; } public Parent Parent { get; set; } } ``` 在这个代码中,我们使用了 `int` 类型的属性 `ParentId`,表示这个孩子所属的父亲的主键。同时,我们也添加了一个导航属性 `Parent`,表示这个孩子所属的父亲对象。 现在,我们可以在代码中添加从表信息了。比如,我们要添加一个名为 `Tom` 的孩子,他的父亲是名为 `John` 的人,我们可以这样写: ```csharp var parent = context.Parents.FirstOrDefault(p => p.Name == "John"); if (parent != null) { var child = new Child { Name = "Tom", Parent = parent }; context.Children.Add(child); context.SaveChanges(); } ``` 在这个代码中,我们首先从数据库查询出了名为 `John` 的父亲对象,然后创建了一个名为 `Tom` 的孩子对象,并将它的 `Parent` 属性设置成 `John` 对象。最后,我们将这个孩子对象添加到 `Children` 集合中,并调用 `SaveChanges` 方法保存到数据库中。 这样,我们就完成了一对多关系的添加从表信息的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值