我有多个查询,如下所示:
var query = from a in EntityAs
select new EntityASmall()
{
// Common Stuff:
Id = a.Id,
Name = a.Name,
ShortName = a.ShortName,
// Specific to EntityA:
ASpecificProperty1 = a.1,
ASpecificProperty2 = a.2
};
var query = from b in EntityBs
select new EntityBSmall()
{
// Common Stuff:
Id = b.Id,
Name = b.Name,
ShortName = b.ShortName,
// Specific to EntityB:
BSpecificProperty1 = b.1,
BSpecificProperty2 = b.2
};
EntityA和EntityB都派生自具有Id
,Name
和ShortName
属性的公共基类。 EntityASmall
和EntityBSmall
也是如此。我有很多看起来像这样的查询,所以我想做一些简单的查询,首先得到常见的东西。我找到了一个看起来很有希望的扩展方法:
public static TSource SetCommonProperties<TSource>(this TSource input, EntityBaseClass entity, Action<TSource> updater) where TSource : EntitySmallBase
{
input.Id = entity.Id;
input.Name = entity.Name;
input.ShortName = entity.Name;
updater(input);
return input;
}
我可以像这样使用它:
var query = from a in EntityAs.AsEnumerable()
select new EntityASmall().SetCommonProperties(a, x =>
{
ASpecificProperty1 = x.1;
ASpecificProperty2 = x.2;
});
请注意AsEnumerable()
。没有它,我得到“一个带有语句体的lambda表达式无法转换为表达式树”,我猜这粗略意味着它试图将Action
部分转换为LINQ-to-SQL的表达式。看起来AsEnumerable()
将集合放在本地完整的位置。对于冗长的帖子感到抱歉,但有没有任何表达方式来编写这个可以与LINQ-to-SQL和Entity Framework一起使用的方法?提前谢谢。
答案 0 :(得分:1)
你想让你的代码DRY,这总是很好的努力。也许你会让你的方法与一些辛劳和劳动以及一些Expression
伏都教,但也许你会去喜欢这个链接:Stop using AutoMapper in your Data Access Code。 (即使您不使用AutoMapper)。
通过这项精彩的工作,您将能够编写简洁的陈述,如:
context.EntityAs.Project().To<EntityASmall>();
context.EntityBs.Project().To<EntityBSmall>();
我自己也用过它,我非常喜欢它。
答案 1 :(得分:0)
您提出的扩展方法看起来不错。
它只是你必须为每个派生实体创建它,并且在你的情况下可能没问题,因为你似乎有几个衍生实体。
其次,我不认为你真的需要在你的扩展方法中传递那个动作委托。 相反,如果可能的话,只在那里调用该方法。我对设计不太了解。
所以你的扩展方法看起来像这样
public static TSource SetCommonProperties<TSource>(this TSource input, EntityBaseClass entity) where TSource : EntitySmallBase
{
input.Id = entity.Id;
input.Name = entity.Name;
input.ShortName = entity.Name;
this.Update(input); // Or this method could exist in any other class or static class.
return input;
}
然后您也可以使用extesion方法。
var query = from a in EntityAs
select new EntityASmall
{
ASpecificProperty1
ASpecificProperty2
}).SetCommonProperties(a,entity)
这将消除您使用AsEnumerable的用法。 如果你想要的话,你也可以用同样的方法从你的基础变换到derviced方法:
DerivceEntityObject SetCommonProperties(BaseEntity)
我希望这能让你了解我在这里建议的内容。