Continued from this solution (thanks Daniel Hilgarth)
return db.Tags.Select(ConstructTagItem());
方法:
private Expression<Func<Tag, TagItem>> ConstructTagItem()
{
return a => new TagItem {ID = a.Id Name = a.Name };
}
其他问题,我如何在这种情况下使用它:
return (from c in db.News_Attributes
select new NewsTagItem
{
NewsID = c.News_Id,
TagID = c.Tag_Id,
Content = c.Content,
Attribute = new TagItem
{
ID = c.Tag.Id,
Name = c.Tag.Name
}
});
我想从其他答案重用该方法:
private Expression<Func<Tag, TagItem>> ConstructTagItem
{
get { return a => new TagItem {ID = a.Id Name = a.Name }; }
}
构建这样的东西:
return (from c in db.News_Attributes
select new NewsTagItem
{
NewsID = c.News_Id,
TagID = c.Tag_Id,
Content = c.Content,
Attribute = ConstructTagItem // TODO: need some way to tell the method that it should use c.Tag
});
我想使用与TagItem多个位置相同的构造。这将使对象更改变得更容易,并保存行。
我想我不得不将c.Tag
定义为ConstructTagItem()
,但我对表达还不太了解。所以我希望有人能帮忙吗?
答案 0 :(得分:0)
我不确定我是否完全了解你要做的事情。 “在这种情况下使用它”是什么意思?你能用这样的东西模仿你以前的技术来封装创建一个NewsTagItem,还是你想要实现的其他东西?
private Expression<Func<News_Attribute, NewsTagItem>> ConstructNewsTagItem()
{
return c => new NewsTagItem
{
NewsID = c.News_Id,
Name = a.Name
TagID = c.Tag_Id,
Content = c.Content,
Attribute = new TagItem
{
ID = c.Tag.Id,
Name = c.Tag.Name
}
}
});
db.News_Attributes.Select(ConstructNewsTagItem());
更新:
好的,我们不能直接重用你的ConstructTagItem(),因为它返回一个包含函数的表达式。你需要的是MemberInitExpression
。手工创建有点棘手,但我们可以使用一个技巧,我们创建我们希望用thunk包装的表达式,这样它就不会被评估,然后抓住thunk的主体来获得表达式。请参阅下面的代码:
private Expression GenerateNewTagItem(TagItem c)
{
Expression<Func<TagItem>> expr = () => new TagItem { ID = c.ID, Name = c.Name };
return expr.Body;
}
使用此功能,我们现在可以完全按照您的要求进行操作:
return (from c in db.News_Attributes
select new NewsTagItem
{
NewsID = c.News_Id,
TagID = c.Tag_Id,
Content = c.Content,
Attribute = GenerateNewTagItem(c)
});
非常整洁吧?