我认为EF的DBContext
和DBSets
是此问题的背景。例如,您可以使用Repository类中的以下代码访问特定集合。
public TEntity Get(int id)
{
return Context.Set<TEntity>().Find(id);
}
Set<TEntity>()
返回TEntity
类型的集合。编码方式如何?我试图找到它的源代码无济于事。我需要创建自己的类并完整写出逻辑吗?
答案 0 :(得分:1)
我猜测Enumerable.OfType<TResult>()
在这里会派上用场。它在源枚举中的类型IEnumerable<TResult>
的所有元素上返回TResult
。至于其实现,MSDN表示:
此方法通过使用延迟执行来实现。立即返回值是一个对象,该对象存储执行操作所需的所有信息。在通过直接调用其GetEnumerator方法或在Visual C#中使用foreach或在Visual Basic中使用For Each枚举该对象之前,不会执行此方法表示的查询。
答案 1 :(得分:1)
我不知道EF是如何做到的,但是您可以轻松地用Types键的Dictionary完成类似的事情
private Dictionary<Type, ICollection> registry = new Dictionary<Type, ICollection>();
// adds a collection of a certain type
public void Add<T>(T collection) where T: ICollection {
registry.Add(typeof(T), collection);
}
// create an empty collection of type T and add it to registry
public void InitCollection<T>() where T: ICollection {
registry.Add(typeof(T), (ICollection)Activator.CreateInstance(typeof(T)));
}
// returns a collection of type T if it has been registered
public T Set<T>() where T: ICollection {
return (T)registry[typeof(T)];
}
答案 2 :(得分:1)
TLDR :EF仅在关键字为DbSet<T>
的字典中创建一个typeof(T)
条目。
看看sourcecode,它的实现方式如下:
/// <summary>
/// Creates a <see cref="DbSet{TEntity}" /> that can be used to query and save instances of <typeparamref name="TEntity" />.
/// </summary>
/// <typeparam name="TEntity"> The type of entity for which a set should be returned. </typeparam>
/// <returns> A set for the given entity type. </returns>
public virtual DbSet<TEntity> Set<TEntity>()
where TEntity : class
=> (DbSet<TEntity>)((IDbSetCache)this).GetOrAddSet(DbContextDependencies.SetSource, typeof(TEntity));
还有Line 195:
/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
object IDbSetCache.GetOrAddSet(IDbSetSource source, Type type)
{
CheckDisposed();
if (!_sets.TryGetValue(type, out var set))
{
set = source.Create(this, type);
_sets[type] = set;
}
return set;
}
sets is处:
private readonly IDictionary<Type, object> _sets = new Dictionary<Type, object>();