我试图找出如何将我使用EF检索到的嵌套集合绑定到asp:ListView或asp:Web表单的Repeater控件。
使用EF我创建了以下查询,其中我选择了一组代理商以及他们与其他代理商共享的实体列表。
public static ICollection<Agency> GetAllAgencies()
{
ICollection<Agency> retAgencies = null;
try
{
using (var context = new InformSecurityEntities(string.Empty))
{
// retAgencies = context.Agencies.OrderBy(a => a.AgencyName).ToList();
retAgencies = (from a in context.Agencies
.Include("SecurityDataShares1")
.OrderBy(a => a.AgencyName)
select a).ToList();
}
}
catch (Exception ex)
{
throw new Exception("Exception thrown in UserFactory.GetAllAgencies() : " + ex.InnerException + ex.Message);
}
return retAgencies;
}
我一直在控制台应用中测试它,它运行正常。在控制台中,我将结果呈现如下:
private static void showAgencies()
{
var results = UserFactory.GetAllAgencies();
foreach (var item in results)
{
Console.WriteLine("Id: {0} || Name: {1}",
item.AgencyId,
item.AgencyName);
foreach (var i in item.SecurityDataShares1)
{
Console.WriteLine(i.ReceivingAgency.AgencyName);
Console.WriteLine(convertEntityToText(i.EntityId));
}
}
Console.WriteLine("enter...");
Console.ReadLine();
}
注意:SecurityDataShares1是ICollection
我希望能够做的是将结果渲染成webform中类似于下面的格式:
Agency 1
Entity 1, Entity 2, Entity 3 ...
Agency 2
Entity 1, Entity 4, Entity 5 ...
我挂起的地方是在控制台应用程序中,我可以访问嵌套集合并迭代它以呈现我的结果。我尝试使用带有辅助嵌套转发器的转发器控件,并将控件绑定到方法结果。
<asp:Repeater ID="agencyListRepeater" runat="server" OnItemDataBound="mainRepeaterBound">
<ItemTemplate>
<div class="itemsRow">
<div class="column-holder">
<asp:Label CssClass="mgmtResultText" ID="lbl_AgencyName" runat="server" Text='<%# Eval("AgencyName") %>' /></div>
<br />
<div class="mgmtIndentDiv">Sharing data with the following agencies:</div>
<asp:Repeater id="nestedDataShare" runat="server">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("SecurityDataShares1.AgencyName") %>' />
<asp:Label runat="server" Text='<%# Eval("SecurityDataShares1.EntityId") %>' />
</ItemTemplate>
</asp:Repeater>
</div>
</ItemTemplate>
</asp:Repeater>
背后的代码
if (userRole.IsSysAdmin)
{
var agencyData = UserFactory.GetAllAgencies();
if (agencyData != null || agencyData.Count > 0)
{
agencyListRepeater.DataSource = agencyData;
agencyListRepeater.DataBind();
}
else
...
但是,只要SecurityDataShares1为null,这就会失败。
对此有何建议或最佳方法?
提前致谢。
答案 0 :(得分:0)
在mainRepeaterBound函数中,您可以获得对代理实体集合的引用。
public void mainRepeaterBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item)
{
System.Web.UI.WebControls.Repeater nestedDataShare = (System.Web.UI.WebControls.Repeater)e.Item.FindControl("nestedDataShare");
Agency item = (Agency)e.Item.DataItem;
nestedDataShare.DataSource = from o in item.SecurityDataShares1 select o;
nestedDataShare.DataBind();
}
}
然后你的内部转发器看起来像:
<asp:Repeater id="nestedDataShare" runat="server">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("AgencyName") %>' />
<asp:Label runat="server" Text='<%# Eval("EntityId") %>' />
</ItemTemplate>
</asp:Repeater>
所以现在你没有通过可能不存在的对象访问属性。
答案 1 :(得分:0)
Eval语句也可用于设置 DataSource 属性。嵌套转发器将具有 SecurityData Shares 列表中使用的类型的Eval语句。
<asp:Repeater ID="nestedDataShare"
runat="server"
DataSource='<%# Eval("SecurityDataShares1")'>
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("AgencyName") %>' />
<asp:Label runat="server" Text='<%# Eval("EntityId") %>' />
</ItemTemplate>
</asp:Repeater>
答案 2 :(得分:0)
我从来没有能够让嵌套的阅读器呈现数据,而它会编译,零(0)结果总是在嵌套对象上返回。结果我找到了另一种解决方案。 请记住,这更像是解决在UI中呈现数据的原始问题。
我决定尝试使用LiteralControl class直接将html注入ui,而不是使用数据阅读器。为了在aspx页面中执行此操作,我添加了一个面板控件。您也可以使用属性为ruant =“server”的div元素,但我决定使用<asp:Panel/>
控件:
所以在ASPX文件中我添加了以下内容:
<asp:Panel ID="agencyList" runat="server" />
然后在我的代码后面,我创建了一个带有两个参数的方法:p = PanelName和a = Collection。
这种方法允许我遍历集合并将结果写为UI作为html。 记住LiteralControl只允许创建不需要服务器端处理的html元素或字符串。因此,如果要添加服务器端控件,则需要使用单独的方法来创建对象{{ 3}}
protected void CreateHtmlResults(System.Web.UI.WebControls.Panel p, ICollection<Agency> a)
{
var results = a;
foreach (var item in results)
{
p.Controls.Add(new LiteralControl("<p><b>" + item.AgencyName + "</b></p>"));
foreach (var i in item.SecurityDataShares1)
{
p.Controls.Add(new LiteralControl(i.ReceivingAgency.AgencyName + " " + i.EntityId +"<br/>"));
}
}
}
然后以如下格式调用它:
if (userRole.IsSysAdmin)
{
//get a list of all agencies
agencyData = UserFactory.GetAllAgencies();
if (agencyData != null || agencyData.Count > 0)
{
CreateHtmlResults(agencyList, agencyData);
}
else
{
//notify UI that no agencies exist
}
}
我仍然感谢任何其他想法或方法,否则我希望这会有所帮助。
-cheers!