我正在使用ASP.NET 3.5 SP1,我有一个问题,我一直坚持。 我有一个ASPX页面,我有2个转发器控件,1个嵌套在另一个中。 从后面的代码我有一个简单的LINQ To Entities查询,它检索数据,然后我将这些数据绑定到转发器控件。 ASPX页面如下所示:
<asp:Repeater ID="rptrMain" runat="server">
<ItemTemplate>
<asp:Label ID="lblName" runat="server" ></asp:Label>
<asp:Label ID="lblDescription" runat="server"></asp:Label>
<asp:Repeater Runat="server" ID="rptrSub">
<ItemTemplate>
<asp:Label ID="lblPartName" runat="server" ></asp:Label>
<asp:Label ID="lblManufacturerName" runat="server" ></asp:Label>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
我将数据绑定到后面代码中的转发器,如下所示:
var q = from inventories in itemContext.Inventory.Include("Parts.Manufacturer")
select inventories;
List<Inventory> inventoryList = q.ToList();
rptrMain.DataSource = inventoryList ;
rptrMain.ItemDataBound += new RepeaterItemEventHandler(rptrMain_ItemDataBound);
rptrMain.DataBind();
void rptrMain_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Inventory inventory = e.Item.DataItem as Inventory;
Label lblName = e.Item.FindControl("lblName") as Label;
Label lblDescription = e.Item.FindControl("lblDescription") as Label;
lblName.Text = inventory.Name;
lblDescription.Text = inventory.Description;
Repeater rptrSub = e.Item.FindControl("rptrSub") as Repeater;
rptrSub.DataSource = inventory.Parts;
rptrSub.ItemDataBound += new RepeaterItemEventHandler(rptrSub_ItemDataBound);
rptrSub.DataBind();
}
}
void rptrSub_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Part part = e.Item.DataItem as Part;
Label lblPartName = e.Item.FindControl("lblPartName ") as Label;
Label lblManufacturerName = e.Item.FindControl("lblManufacturerName") as Label;
lblPartName.Text = part.Name;
lblManufacturerName.Text = part.Manufacturer.Name
}
}
库存与零件有1对多的关系,而零件与制造商有多对一的关系。
现在我的问题是:如何在LINQ查询中过滤Inventory的子实体? 例如,我只想检索某个PartType的所有零件。 像这样:
where parts.Type == Tire
我确实找到了这个有用的提示http://blogs.msdn.com/b/alexj/archive/2009/06/02/tip-22-how-to-make-include-really-include.aspx 虽然那仍然不允许我过滤子实体?
答案 0 :(得分:1)
我认为最好的方法是在调用DataBind()之前过滤用于rptrMain的数据源。 例如,代码可能是这样的:
var q = from inventories in itemContext.Inventory.Include("Parts.Manufacturer")
where inventories.Part.Type == Tire
select inventories;
...
我声明了两个新类,包括格式化查询所需的字段:
class AbstractPartsClass
{
public string Name { get; set; }
public string ManufacturerName { get; set; }
}
class AbstractInventoryClass
{
public string Name { get; set; }
public string Description { get; set; }
public List<AbstractPartsClass> AbstractParts { get; set; }
}
然后我更改了查询和部分代码,如下所示:
var q = from inventory in itemContext.Inventory.Include("Parts.Manufacturer")
let filteredParts = from part in inventory.Parts
where part.Type == Tire //any filter condition
select new AbstractPartsClass()
{
Name = part.Name,
ManufacturerName = part.ManufacturerName
}
select new AbstractInventoryClass()
{
Name = inventory.Name,
Description = inventory.Description,
AbstractParts = filteredParts.ToList(),
};
List<AbstractInventoryClass> inventoryList = q.ToList();
rptrMain.DataSource = inventoryList ;
rptrMain.ItemDataBound += new RepeaterItemEventHandler(rptrMain_ItemDataBound);
rptrMain.DataBind();
void rptrMain_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Inventory inventory = e.Item.DataItem as AbstractInventoryClass; //changed line
Label lblName = e.Item.FindControl("lblName") as Label;
Label lblDescription = e.Item.FindControl("lblDescription") as Label;
lblName.Text = inventory.Name;
lblDescription.Text = inventory.Description;
Repeater rptrSub = e.Item.FindControl("rptrSub") as Repeater;
rptrSub.DataSource = inventory.AbstractParts; //changed line
rptrSub.ItemDataBound += new RepeaterItemEventHandler(rptrSub_ItemDataBound);
rptrSub.DataBind();
}
}
void rptrSub_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Part part = e.Item.DataItem as AbstractPartsClass; //changed line
Label lblPartName = e.Item.FindControl("lblPartName ") as Label;
Label lblManufacturerName = e.Item.FindControl("lblManufacturerName") as Label;
lblPartName.Text = part.Name;
lblManufacturerName.Text = part.ManufacturerName
}
}