Can I create a MemberInitExpression
or any expression of a parameterless constructor from a function that literally returns a parameterless constructor?
public IQueryable<GroupView> GetViewSelect(IQueryable<ItemGroup> myQ)
{
return myQ.SelectMany(GetExpression1(), GetExpression2());
}
internal static Expression<Func<ItemGroup, IEnumerable<ItemDetail>>>
GetExpression1()
{
// m is the ItemGroup
// m.item is Item
// m.item.itemDetail is a collection of ItemDetail
return m => m.item.itemDetail;
}
internal static Expression<Func<ItemGroup, ItemDetail, GroupView>>
GetExpression2()
{
// m is the ItemGroup
// n is the ItemDetail
// and it's error at runtime coz LINQ doesnt know the GetGroupView.. :(
return (m, n) => GetGroupView(m, n);
}
internal static GroupView GetGroupView(ItemGroup m, ItemDetail n)
{
// I think the same error will occurs
// coz LINQ doesnt know the GetItemView and GetItemDetailView
return new GroupView
{
Id = m.id,
Name = m.name,
ItemDetailsTotalCount =
m.item.ItemDetails.Sum(nn => nn.item.itemDetails.Count),
Item = GetItemView(m.item),
ItemDetail = GetItemDetailView(n)
};
}
internal static ItemView GetItemView(Item m)
{
return new ItemView
{
Id = m.id,
Name = m.name,
DetailCount = m.ItemDetail.Count
};
}
internal static ItemDetailView GetItemDetailView(ItemDetail n)
{
return new ItemDetailView
{
Id = n.id,
Name = n.name,
Supplier = GetSupplierView(n.supplier)
};
}
internal static SupplierView GetSupplierView(Supplier n)
{
return new SupplierView
{
Id = n.id,
Name = n.name,
Email = n.email ?? "no email",
Phone = n.phone ?? "no phone"
};
}
Of course none of those above works,.. but I just want to avoid retyping the same parameterless constructor over and over in order to get the view constructor every time I want to get different view..
For example, I'd like to call it like this
public IQueryable<ItemView> GetViewSelect(IQueryable<Item> myQ)
{
return myQ.Select(GetExpression3());
}
public IQueryable<ItemView> GetViewSelect(IQueryable<ItemDetail> myQ)
{
return myQ.Select(GetExpression3());
}
internal static Expression<Func<Item, ItemView>> GetExpression3()
{
return m => GetItemView(m);
}
internal static Expression<Func<ItemDetail, ItemView>> GetExpression4()
{
return m => GetItemView(m.item);
}
instead of writing the same parameterless constructor everytime I call it like this below..
internal static Expression<Func<Item, ItemView>> GetExpression3()
{
// writing same parameterless constructor again
return m => new ItemView
{
Id = m.id,
Name = m.name,
DetailCount = m.ItemDetail.Count
};
}
internal static Expression<Func<ItemDetail, ItemView>> GetExpression4()
{
// the same thing again
return m => new ItemView
{
Id = m.item.id,
Name = m.item.name,
DetailCount = m.item.ItemDetail.Count
};
}
internal static Expression<Func<ItemGroup, ItemDetail, GroupView>>
GetExpression2()
{
return (m, n) => new GroupView
{
Id = m.id,
Name = m.name,
ItemDetailsTotalCount =
m.item.ItemDetails.Sum(nn => nn.item.itemDetails.Count),
Item = new ItemView
{
Id = m.item.id,
Name = m.item.name,
DetailCount = m.item.ItemDetail.Count
},
ItemDetail = new ItemDetailView
{
Id = n.id,
Name = n.name,
Supplier = new SupplierView
{
Id = n.id,
Name = n.name,
Email = n.email ?? "no email",
Phone = n.phone ?? "no phone"
}
}
};
}
So I was actually looking for a way to convert
new ItemView
{
Id = m.id,
Name = m.name,
DetailCount = m.ItemDetail.Count
}
into a MemberInitExpression
parameterless constructor so maybe I can use it like below without doing any member-assignment..
internal Expression<Func<Item, ItemView>> GetExpression4e
(ParameterExpression m)
{
// looking for something like this..
MemberInitExpression ItemViewInitExpression =
Something("GetItemView", new Object[] {m});
return Expression.Lambda<Func<Item, ItemView>>
(ItemViewInitExpression, m);
}