【发布时间】:2020-01-27 03:12:38
【问题描述】:
我正在从数据库中查询多个相关表并将它们映射到类。出于性能原因,我分别查询每个表并将它们加入我的代码中,而不是使用 SQL 连接。使用foreach 循环为每个级别进行连接相当简单,但感觉是多余的,因此我尝试对其进行抽象。
我有一个基类Entity 和两个接口IParent 和IChild:
public abstract class Entity<TId> : IEquatable<Entity<TId>>
{
public TId Id { get; set; }
}
public interface IParent<TParent, TParentId, TChild, TChildId>
where TChild : Entity<TChildId>, IChild<TChild, TChildId, TParent, TParentId>
where TParent : Entity<TParentId>, IParent<TParent, TParentId, TChild, TChildId>
{
ICollection<TChild> Children { get; set; }
}
public interface IChild<TChild, TChildId, TParent, TParentId>
where TParent : Entity<TParentId>, IParent<TParent, TParentId, TChild, TChildId>
where TChild : Entity<TChildId>, IChild<TChild, TChildId, TParent, TParentId>
{
TParent Parent { get; set; }
TParentId ParentId { get; set; }
}
实体表示数据库表的抽象,在一对多的关系中,父是一,子是多。我写了AddChildren 这样的方法:
public partial class Helpers
{
public static void AddChildren<TParent, TParentId, TChild, TChildId>(
IDictionary<TParentId, TParent> parents,
IList<TChild> children)
where TParent : Entity<TParentId>, IParent<TParent, TParentId, TChild, TChildId>
where TChild : Entity<TChildId>, IChild<TChild, TChildId, TParent, TParentId>
{
foreach (var child in children)
{
parents[child.ParentId].Children.Add(child);
}
}
public static void AddChildren<T1, T1Id, T2, T2Id, T3, T3Id>(
IDictionary<T1Id, T1> t1,
IDictionary<T2Id, T2> t2,
IList<T3> t3)
where T1 : Entity<T1Id>, IParent<T1, T1Id, T2, T2Id>
where T2 : Entity<T2Id>, IChild<T2, T2Id, T1, T1Id>, IParent<T2, T2Id, T3, T3Id>
where T3: Entity<T3Id>, IChild<T3, T3Id, T2, T2Id>
{
AddChildren<T2, T2Id, T3, T3Id>(t2, t3);
AddChildren<T1, T1Id, T2, T2Id>(t1, t2.Values.ToList());
}
}
每当我实现接口和调用方法时,我对必须指定所有类型参数并不特别兴奋。简单的类如下所示:
public class MyGuidParentEntity : Entity<System.Guid>, IParent<MyGuidParentEntity, System.Guid, MyLongChildEntity, long>
{
public ICollection<MyLongChildEntity> Children { get; set; }
}
public class MyLongChildEntity : Long.Entity, IChild<MyLongChildEntity, long, MyGuidParentEntity, System.Guid>
{
public MyGuidParentEntity Parent { get; set; }
public System.Guid ParentId { get; set; }
}
简单的方法调用如下所示:
Helpers.AddChildren<MyGuidParentEntity, System.Guid, MyLongChildEntity, long>(parents, children);
有没有办法缩短/删除泛型类型参数?如果不是来自类声明,那么来自AddChildren 方法?我很想能够做到AddChildren(parents, children) 并整理出类型。即使AddChildren<TParent, TChild>(parents, children) 也会有所改进。
或者,有没有更好的方法来解决这个问题?我是否因为试图抽象事物太多而自取其辱?
【问题讨论】:
-
◾ 有什么方法可以简化泛型参数? → 像什么简化?以什么成本,失去一些约束或失去一些功能?
-
◾ 我应该做一些完全不同的事情吗? → 您分享了您的解决方案,但没有说明您要满足的要求。
-
这是代码审查吗?
-
出于性能原因,我分别查询每个表并将它们加入我的代码中,而不是使用 SQL 连接。 => 这让我很困惑!那么,当您需要加入 3 个表中的数百万条记录时会发生什么?将它们全部放入内存,连接对象?
-
通过网络从服务器中提取所有数据以将它们加入内存是一个糟糕的主意,不要这样做。 SQL 在服务器上完成所有工作,然后通过网络发送您真正需要的数据。