Как отобразить данные из вложенной коллекции ICollection в веб-форме asp.net - PullRequest
0 голосов
/ 03 апреля 2012

Я пытаюсь выяснить, как связать вложенную коллекцию, которую я извлек с помощью EF, в элемент управления asp: ListView или asp: 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

Что я хотел бы сделать, это взять результаты и отобразить их вформат, подобный приведенному ниже, в веб-форме:

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 будет нулевым.

Любые предложения или лучший подход для этого?

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 03 апреля 2012

Оператор Eval также можно использовать для установки свойства DataSouce .Тогда вложенный повторитель будет иметь операторы Eval для типа, используемого в списке SecurityDataShares1 .

 <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>
0 голосов
/ 03 апреля 2012

Мне никогда не удавалось заставить вложенный считыватель отображать данные, пока он компилировался, нулевые (0) результаты всегда возвращались для вложенных объектов.В результате я искал альтернативное решение. Имейте в виду, что это скорее обходной путь к исходному вопросу для визуализации данных в пользовательском интерфейсе .

Вместо использования устройства чтения данных я решил попробовать внедрить html непосредственно в пользовательский интерфейс, используя класс LiteralControl .Для этого на странице aspx я добавил панель управления.Вы также можете использовать элемент div с атрибутом ruant = "server", но я решил использовать элемент управления <asp:Panel/>:

Поэтому в файле ASPX я добавил следующее:

       <asp:Panel ID="agencyList" runat="server" />

Затем в своем коде я создал метод с двумя параметрами p = PanelName и a = Collection.

Этот подход затем позволил мне перебрать коллекцию и записать в пользовательский интерфейс результаты в виде html. Помните, что LiteralControl позволяет создавать только HTML-элементы или строки, которые не требуют обработки на стороне сервера. Поэтому, если вы хотите добавить серверные элементы управления, вам потребуется использовать отдельный метод для создания объекта Посмотрите здесь пример

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
 }
 }

Я все равно буду признателен за любые альтернативные идеи или подходы, иначе я надеюсь, что этопомогает.

-чисток!

0 голосов
/ 03 апреля 2012

В вашей функции 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>

Так что теперь вы не обращаетесьсвойство через объект, которого там может не быть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...