2013-12-23 9 views
0

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

Мой ретранслятор находится на моей странице «show.aspx», и у меня есть другой класс, где у меня есть методы привязки данных.

Итак, каков наилучший способ привязки ретранслятора от моего класса данных?

Кроме того, я сделал метод расширения для ретранслятора, который называется BindTable(); Мне легко привязывать данные, просто называя этот метод в классе show.cs (я имею в виду при загрузке формы). Этот метод принимает sql-запрос как параметр, и все делается в фоновом режиме методом расширения.

rptDisplay.BindTable("select * from table"); 

Но я ищу лучший подход. Не могу ли я получить доступ к моему ретранслятору из моего класса данных, где находятся все мои методы привязки данных?

+1

Что вы подразумеваете под «моим классом данных, где находятся все мои методы привязки данных»? Какова цель «класса данных», доступа к данным или выполнения привязки данных для элементов управления? – Markus

+0

Позвольте мне сделать это простым! Я хочу привязать ретранслятор ретранслятора из другого класса, скажем, «abc.cs». Причина для этого, я хочу сделать код чистым. Я просто хочу вызвать функцию в событии загрузки формы, и мой ретранслятор должен затухать данные. И эта функция написана в моем классе «abc.cs». Как это можно достичь? – askBittu

+0

Почему вы не передаете ретранслятор методу в своем классе? – afzalulh

ответ

0

У вас может быть функция класса abc, которая принимает параметр ретранслятора в качестве параметра и связывает данные с ним.

EDIT: Возможно, вы захотите переключить источник данных для разных ретрансляторов. В этом случае вы можете добавить еще один параметр в метод BindTable и внутри этого метода проверить параметр, чтобы переключиться на правильный источник данных.

EDIT 2:BindTable принимает два параметра, Repeater и перечисление MyEnum.

Вот как я это сделаю. У меня есть страница, Show.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Show.aspx.cs" Inherits="RepeaterTestOne.Show" %> 

<!DOCTYPE html> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title></title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <div> 
     <asp:Repeater ID="rptDisplay" runat="server"> 
      <HeaderTemplate> 
       <table> 
      </HeaderTemplate> 
      <ItemTemplate> 
       <tr> 
        <td> 
         <asp:Label ID="lblID" runat="server" Text='<%#Eval("ID") %>'></asp:Label> 
        </td><td> 
         <asp:Label ID="lblName" runat="server" Text='<%#Eval("Name") %>'></asp:Label> 
        </td> 
       </tr> 
      </ItemTemplate> 
      <FooterTemplate> 
       </table> 
      </FooterTemplate> 
     </asp:Repeater> 
     <asp:Button ID="Button1" runat="server" Text="First One" OnClick="Button1_Click" /> 
     <asp:Button ID="Button2" runat="server" Text="First Four" OnClick="Button2_Click" /> 
     <asp:Button ID="Button3" runat="server" Text="All" OnClick="Button3_Click" /> 
    </div> 
    </form> 
</body> 
</html> 

В коде я звоню BindTable() метод моего класса данных (MyDataClass) и передачи повторителя. Мой Show.aspx.cs выглядит следующим образом:

using System; 

namespace RepeaterTestOne 
{ 
    public partial class Show : System.Web.UI.Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 
     } 

     protected void Button1_Click(object sender, EventArgs e) 
     { 
      MyDataClass.BindTable(rptDisplay, MyEnum.FirstOne); 
     } 

     protected void Button2_Click(object sender, EventArgs e) 
     { 
      MyDataClass.BindTable(rptDisplay,MyEnum.FirstFour); 
     } 

     protected void Button3_Click(object sender, EventArgs e) 
     { 
      MyDataClass.BindTable(rptDisplay, MyEnum.AllItems); 
     } 
    } 
} 

В моей MyDataClass У меня есть код (с фиктивным кодом для теста), как это:

using System.Collections.Generic; 
using System.Web.UI.WebControls; 

namespace RepeaterTestOne 
{ 
    public static class MyDataClass 
    { 
     public static void BindTable(Repeater rpt, MyEnum mySelection = MyEnum.AllItems) 
     { 

      //Replace this part with custom sql 
      List<MyData> lst = new List<MyData>() 
      { 
       new MyData{ID=1, Name="Item 1"}, 
       new MyData{ID=2, Name="Item 2"}, 
       new MyData{ID=3, Name="Item 3"}, 
       new MyData{ID=4, Name="Item 4"}, 
       new MyData{ID=5, Name="Item 5"} 
      }; 
      switch (mySelection) 
      { 
       case MyEnum.FirstOne: 
        lst = new List<MyData>(){new MyData{ID=1, Name="Item 1"}}; 
        break; 
       case MyEnum.FirstFour: 
        lst = new List<MyData>() 
        { 
         new MyData{ID=1, Name="Item 1"}, 
         new MyData{ID=2, Name="Item 2"}, 
         new MyData{ID=3, Name="Item 3"}, 
         new MyData{ID=4, Name="Item 4"} 
        }; 
        break; 
       default: 
        lst = new List<MyData>() 
        { 
         new MyData{ID=1, Name="Item 1"}, 
         new MyData{ID=2, Name="Item 2"}, 
         new MyData{ID=3, Name="Item 3"}, 
         new MyData{ID=4, Name="Item 4"}, 
         new MyData{ID=5, Name="Item 5"} 
        }; 
        break; 
      } 
      //Replace this part with custom sql 

      rpt.DataSource = lst; 
      rpt.DataBind(); 
     } 

    } 
    public class MyData 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
    } 
} 

И вот мое перечисление MyEnum:

namespace RepeaterTestOne 
{ 
    public enum MyEnum 
    { 
     AllItems = 1, 
     FirstOne = 2, 
     FirstFour = 3 
    } 
} 
+0

Хорошо. Это кажется хорошим, пока у меня есть только один повторитель в моем классе. Но что, если у меня есть несколько повторителей на моей странице? Таким образом, я не могу использовать код. Мне придется писать разные функции для привязки разных ретрансляторов. – askBittu

+0

Скажите, что у вас есть еще один повторитель с ID = «anotherRepeater». Вы назовете его как 'MyDataClass.BindTable (anotherRepeater);'. Независимо от того, сколько у вас повторителей вы можете вызвать их, используя эту функцию. – afzalulh

+0

@askBittu - обновленный код, чтобы показать, как вы можете использовать ту же функцию для любых номеров ретранслятора. – afzalulh

1

Основываясь на ваших комментариях, ваша цель состоит в том, чтобы разложить код, который связывает данные с формой, чтобы сохранить код формы в чистоте. Это хорошо, так как код для извлечения и привязки данных может быть большой частью вашего кода за файлами.
Прежде всего, я думаю, что создание метода расширения, как вы уже сделали, очень хороший и элегантный способ приблизиться к этому. Он хорошо работает для нескольких повторителей на странице и разных операторов SQL. Итак, как вы можете улучшить это?

Теперь вы предоставляете операторы SQL методу расширения непосредственно в коде позади. Это работает, но для того, чтобы иметь действительно чистое разделение проблем, я бы не предложил включать утверждения непосредственно в код пользовательского интерфейса, поскольку это деталь доступа к данным, в которой он использует SQL. Если вы решите внедрить сервисный уровень в более поздний момент времени, предоставляя данные, вам придется внести много изменений в свой код пользовательского интерфейса. Это зависит от вас, чтобы решить, является ли это реалистичным сценарием в вашем контексте, который стоит усилий.
шаги заключаются в следующем:

  1. Создание объектов передачи данных (DTO), которые содержат данные, которые имеют отношение к вашему UI.
  2. Создайте классы доступа к данным (также называемые классами репозитория), которые не возвращают DataTables/Sets, а коллекции или отдельные DTO с такими методами, как GetById, GetAll, GetByName, которые отображают соответствующие запросы к базе данных. MicroORM (например, Dapper.NET) может поддерживать вас в процессе (бурения) сопоставления из объектов базы данных (DataTables, DataReaders) в DTO. Также включают методы обновления базы данных.
  3. В форме вы можете получить данные по вызову в репозиторий и связать ретранслятор с коллекцией DTO.

После того, как вы ввели эти изменения, вы заметите, что код привязки данных не превратился в код, а код доступа к данным. Когда этот код перемещается в репозитории, привязка данных просто устанавливает свойство DataSource и вызов DataBind(). Таким образом, ваш метод расширения будет очень мала и выглядеть примерно так:

public static void Bind<T>(this Repeater rpt, IEnumerable<T> data) 
{ 
    rpt.DataSource = data; 
    rpt.DataBind(); 
} 

Этот подход требует некоторых усилий, но обеспечивает гораздо лучшее разделение задач как UI независимой логики доступа к данным находится в отдельном месте (возможно, вы также можете разделить код доступа к данным с другими проектами для разных клиентов, например WPF или WinForms). Кроме того, я уверен, что вы сможете идентифицировать множество других мест (помимо привязки данных), где вы также можете использовать репозитории вместо прямого доступа к данным. Это также сделает ваш код короче.

+0

Вы точно поняли мою точку зрения. Я использовал метод расширения для привязки данных для нескольких повторителей в моем другом проекте. Как бы то ни было, мой код был очень коротким, но мне действительно не нравилось, что идея запроса sql-запроса напрямую связана с абстрактным кодом. – askBittu

+0

Я собираюсь попробовать ваш метод точно. Однако моя потребность очень проста. Я просто пытаюсь отобразить статью и комментарии из базы данных. Я просто хочу предоставить идентификатор статьи из строки запроса, а затем вызвать метод show, чтобы сделать все. – askBittu

+0

@askBittu: хорошо знать, что я правильно понял ваш вопрос. Вы должны судить, слишком ли накладные расходы в конкретной ситуации.С другой стороны, хорошая основа для MicroORM будет выполнять большую часть дополнительной работы. – Markus

Смежные вопросы