【发布时间】:2017-01-10 12:27:36
【问题描述】:
我正在尝试编写从数据库实体到应用程序读取模型的自定义映射。
假设我有 2 个实体
public class A
{
public string One {get; set;}
public string Two {get; set;}
public ICollection<B> Three {get;set;}
}
public class B
{
public string SomeProp {get; set;}
public string SomeProp2 {get; set;}
}
我正在尝试将这些实体映射到读取模型。
public class AReadModel
{
public string One {get; set;}
public string Two {get; set;}
public ICollection<BReadModel> Three {get;set;}
public bool Deletable {get; set;}
}
public class BReadModel
{
public string SomeProp {get; set;}
public string SomeProp2 {get; set;}
}
这种关系中的实体 B 是 Collection 但在另一个中它可以是独立的 1 : 1 或 1 : 0 关系,所以我想将 A 和 AReadModel 以及 B 和 BReadModel 之间的映射定义为表达式,将作为 IQueryable Select 传递()。关键是我想在 A -> AReadModel 的定义中重用 B -> BReadModel 的映射并将其定义为 IQueryable 自定义扩展。
public static class BMapping
{
public Expression<Func<B,BReadModel>> expression = instance => new BReadModel
{
SomeProp = instance.SomeProp,
SomeProp2 = instance.SomeProp
};
public static IQueryable<BReadModel>ToReadModel(this IQueryable<B> source)
{
return this.Select(expression);
}
}
public static class AMapping
{
public Expression<Func<A,AReadModel>> expression = instance => new AReadModel
{
One = instance.One,
Two = instance.Any,
Deletable = Three.Any(),
Three = instance.Three.Select(BMapping.expression) // this will not work cuz Three is collection and it requires Func<B,BReadModel> yet i need an expression here, otherwise EF won't be able to translate it. Of course I could just explicitly define mapping here again and it would work but it will lead to maintenance hell.
public static IQueryable<AReadModel>ToReadModel(this IQueryable<A> source)
{
return this.Select(expression);
}
}
所以问题是:是否可以在映射定义中为 AMapping 中的嵌套集合重用 BMapping 中定义的映射?
【问题讨论】:
-
查看 LinqKit。 albahari.com/nutshell/linqkit.aspx
-
为什么不直接使用普通的 EF,然后使用 AutoMapper 转换为您的自定义类。但我想知道.. 你想达到什么目的.. 为什么首先使用 ReadModels?
-
@Seabizkit 答案很简单。带有延迟加载的 EF 让您只下载实体中包含的数据。让我们假设三个集合映射到一个表,并且这个集合(表)的大小在应用程序运行期间将至少以线性方式增加(比如 A 是一个测试,B 是一个测试实例)。所以一个测试可以有数千个测试实例。我不想沿着我的实体下载这么大的集合,但我需要一些只能在这个集合上计算的数据。 (示例:Deletable = Three.Any())(在应用端的 DB 很便宜)
-
换句话说,ReadModels 让我将大量计算移至数据库并由 ReadModel 通过仅对 db 的一次查询来构建 + i 保护自己免受无意中将大型集合从 db 下载到应用程序的应用程序(通过我意味着通过简单的查询在实体上调用三个集合上的任何一个,这将导致下载三个集合只是为了检查它的空性)。
-
@user2184057 延迟加载与我所说的任何事情有关。你有一个包含实体集合的实体......好吧,现在你担心卷......好吧,但你并没有真正解释问题出在哪里。过滤你需要的东西,只使用它..简单。尝试用简单的术语解释你想要克服什么......看起来像处理大量......你是否在你的问题“大量计算”中抽象了一些细节这些是如何存储的。你能用上面代码的用例更新一下吗?
标签: c# .net entity-framework expression ienumerable