Many-to-many relationships in EF Core 2.0 – Part 4: A more general abstraction
In the last few posts we saw how to hide use of the join entity from two entities with a many-to-many relationship. This post doesn’t add any additional functionality, it just abstracts some of what we saw so it can be re-used more easily.
To start with we define an interface for join entities:
public interface IJoinEntity<TEntity>
{
TEntity Navigation { get; set; }
}
Any join entity will implement this interface twice; once for each side:
public class PostTag : IJoinEntity<Post>, IJoinEntity<Tag>
{
public int PostId { get; set; }
public Post Post { get; set; }
Post IJoinEntity<Post>.Navigation
{
get => Post;
set => Post = value;
} public int TagId { get; set; }
public Tag Tag { get; set; }
Tag IJoinEntity<Tag>.Navigation
{
get => Tag;
set => Tag = value;
}
}
We can now re-write our facade colection to use any types that implement this interface:
public class JoinCollectionFacade<TEntity, TOtherEntity, TJoinEntity>
: ICollection<TEntity>
where TJoinEntity : IJoinEntity<TEntity>, IJoinEntity<TOtherEntity>, new()
{
private readonly TOtherEntity _ownerEntity;
private readonly ICollection<TJoinEntity> _collection; public JoinCollectionFacade(
TOtherEntity ownerEntity,
ICollection<TJoinEntity> collection)
{
_ownerEntity = ownerEntity;
_collection = collection;
} public IEnumerator<TEntity> GetEnumerator()
=> _collection.Select(e => ((IJoinEntity<TEntity>)e).Navigation).GetEnumerator(); IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator(); public void Add(TEntity item)
{
var entity = new TJoinEntity();
((IJoinEntity<TEntity>)entity).Navigation = item;
((IJoinEntity<TOtherEntity>)entity).Navigation = _ownerEntity;
_collection.Add(entity);
} public void Clear()
=> _collection.Clear(); public bool Contains(TEntity item)
=> _collection.Any(e => Equals(item, e)); public void CopyTo(TEntity[] array, int arrayIndex)
=> this.ToList().CopyTo(array, arrayIndex); public bool Remove(TEntity item)
=> _collection.Remove(
_collection.FirstOrDefault(e => Equals(item, e))); public int Count
=> _collection.Count; public bool IsReadOnly
=> _collection.IsReadOnly; private static bool Equals(TEntity item, TJoinEntity e)
=> Equals(((IJoinEntity<TEntity>)e).Navigation, item);
}
The main advantage of this new abstraction is that specific delegates to select target entities and create join entities are not needed anymore. So now in our entities we can create collections like so:
public class Post
{
public Post() => Tags = new JoinCollectionFacade<Tag, Post, PostTag>(this, PostTags); public int PostId { get; set; }
public string Title { get; set; } private ICollection<PostTag> PostTags { get; } = new List<PostTag>(); [NotMapped]
public ICollection<Tag> Tags { get; }
} public class Tag
{
public Tag() => Posts = new JoinCollectionFacade<Post, Tag, PostTag>(this, PostTags); public int TagId { get; set; }
public string Text { get; set; } private ICollection<PostTag> PostTags { get; } = new List<PostTag>(); [NotMapped]
public IEnumerable<Post> Posts { get; }
}
Everything else, including the little test application, is unchanged from the previous post.
Many-to-many relationships in EF Core 2.0 – Part 4: A more general abstraction的更多相关文章
- Many-to-many relationships in EF Core 2.0 – Part 1: The basics
转载这个系列的文章,主要是因为EF Core 2.0在映射数据库的多对多关系时,并不像老的EntityFramework那样有原生的方法进行支持,希望微软在以后EF Core的版本中加入原生支持多对多 ...
- Many-to-many relationships in EF Core 2.0 – Part 2: Hiding as IEnumerable
In the previous post we looked at how many-to-many relationships can be mapped using a join entity. ...
- Many-to-many relationships in EF Core 2.0 – Part 3: Hiding as ICollection
In the previous post we ended up with entities that hide the join entity from the public surface. Ho ...
- EF Core 1.0 和 SQLServer 2008 分页的问题
EF Core 1.0 在sqlserver2008分页的时候需要指定用数字分页. EF Core1.0 生成的分页语句中使用了 Featch Next.这个语句只有在SqlServer2012的时候 ...
- ASP.NET Core 开发-Entity Framework (EF) Core 1.0 Database First
ASP.NET Core 开发-Entity Framework Core 1.0 Database First,ASP.NET Core 1.0 EF Core操作数据库. Entity Frame ...
- EF Core 1.0中使用Include的小技巧
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:由于EF Core暂时不支持Lazy Loading,所以利用Include来加载额外 ...
- .NET Core 1.0、ASP.NET Core 1.0和EF Core 1.0简介
.NET Core 1.0.ASP.NET Core 1.0和EF Core 1.0简介 英文原文:Reintroducing .NET Core 1.0, ASP.NET Core 1.0, and ...
- EF Core 2.0 新特性
前言 目前 EF Core 的最新版本为 2.0.0-priview1-final,所以本篇文章主要是针对此版本的一些说明. 注意:如果你要在Visual Studio 中使用 .NET Core 2 ...
- EF Core 2.0使用MsSql/Mysql实现DB First和Code First
参考地址 EF官网 ASP.NET Core MVC 和 EF Core - 教程系列 环境 Visual Studio 2017 最新版本的.NET Core 2.0 SDK 最新版本的 Windo ...
随机推荐
- css3之背景定位
属性: background-position: left top || left bottom || right top || right bottom || center center || 像素 ...
- ArcGIS for JavaScript 关于路径开发的一些记录(三)
最近被一个bug困扰了两天~ 我新发布了一个NAserver(路径分析服务),但是放在之前的代码里面发现不能生成路径.经过我的调试发现并没有代码并没有报错,并且能够返回所生成路径的Graphic la ...
- kafka leader平衡策略
1.1个partition的默认leader是replicas中的第一个replica 2.kafka controller会启动一个定时的check线程,kafka默认是5min周期,mafka是3 ...
- windows 64位 安装mvn提示 不是内部或外部命令
在安装mvn的过程中当在mvn的目录下去执行mvn命令的时候是可以正常执行的,当设置好环境变量后执行后发现提示mvn不是内部命令. 原因是设置的MAVEN_HOME变量未被Path解析,解决办法是 直 ...
- canvas中的非零环绕原则
非零环绕原则: 如果需要判断某一个区域是否需要填充颜色. 就从该区域中随机的选取一个点. 从这个点拉一条直线出来, 一定要拉到图形的外面. 此时以该点为圆心.看穿过拉出的直线的线段. 如果是顺时针方向 ...
- 实现UILabel渐变色效果
实现UILabel渐变色效果 效果如下图: 源码: // // CombinationView.h // ChangeColorLabel // // Created by YouXianMing o ...
- [问题记录]libpomelo编译报错:ssize_t重定义
1. 时间:2015/01/16 描述:添加libpomelo到cocos2dx项目,报错如下图所示: 解决: 修改代码,源代码: #if !defined(_SSIZE_T_) && ...
- Hyperledger Fabric 1.0 学习搭建 (四)--- 创建Fabric多节点集群
4.1.配置说明 首先可以根据官方Fabric自带的e2e_cli列子中的集群方案来生成我们自己的集群,与案例不同的是我们需要把容器都分配到不同的服务器上,彼此之间通过网络来进行通信,网络构建完成后则 ...
- windows生成硬链接
因工作电脑需要同时使用pl/sql和toad工具需要同时配置32位和64位oracle client如此增加了维护tnsnames.ora的复杂程度使用windows硬链接可以减少工作量,每次只修改源 ...
- python UI自动化实战记录四:测试页面1-pageobject
该部分记录测试页面1-IndexPage,所有首页上的元素定位.操作.获取属性等方法都写在该类中. 1 首页类继承自BasePage 2 首页类第一部分写的是所有的定位器 3 首页类第二部分类的方法, ...