Доступ к информации из таблиц, связанных с FK, с помощью LINQ - PullRequest
2 голосов
/ 06 мая 2009

Я работаю над системой планирования сотрудников. Я думаю, что у меня достаточно хорошо настроена база данных, и я столкнулся с проблемой при извлечении данных для моей базы данных и их переносе на страницу. Я использую LINQ, чтобы облегчить себе жизнь.

Здесь - реляционная карта объекта.

Вот мой оператор выбора Linq:

protected void LinqSelecting(object sender, LinqDataSourceSelectEventArgs e) {
    MilhouseDataClassesDataContext mdb = new MilhouseDataClassesDataContext();
    e.Result = from x in mdb.MilhouseHours
               group x by x.HourString into hour
               select new {
                   hourStr=hour.Key,
                   uName=hour};
 }

Вот соответствующие части моего кода GridView:

        <asp:GridView ID="GridView1" runat="server" DataSourceID="LinqDataSource1" AutoGenerateColumns="false">
            <asp:TemplateField HeaderText="Sunday">
                <ItemTemplate>
                    <asp:CheckBoxList ID="shiftsSun" runat="server" DataSource='<%#Eval("uName")%>' DataValueField="UserId" />
                </ItemTemplate>
            </asp:TemplateField>
            ...
        </asp:Gridview>

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

group x.aspnet_User by x.HourString into hour

Я думаю, что мне здесь не хватает большой концепции. Используя группу, я должен иметь доступ к членам класса aspnet_user через член uName моего анонимного класса ... или так я думал!

edit: Вот несколько скриншотов переменных, захваченных при отладке.

е. Результат | aspnet_User

Моя конечная цель - иметь сетку, которая будет показывать список рабочих смен в течение часа каждого дня в каждой ячейке. Любой дизайн или помощь кода будет принята с благодарностью. Кажется, я не могу обойти это.

Ответы [ 2 ]

2 голосов
/ 07 мая 2009

Перебирает коллекцию, содержащую объекты MilhouseHour: IGrouping. MilhouseHour действительно содержит ссылку на aspnet_User, но то, на что вы хотите сослаться, имя (и идентификатор) является свойством aspnet_User, а не MilhouseHour. В идеале вы могли бы написать разметку как

  <asp:CheckBoxList ID="shiftsSun" runat="server" 
    DataSource='<%#Eval("hourUsers")%>' 
    DataTextField = "aspnet_User.UserName"
    DataValueField = "aspnet_User.UserId" />

Но это дает ошибку. ASP.Net ожидает в DataTextField имя свойства, которое оно будет вызывать (предположительно путем отражения) для рассматриваемого объекта, а не выражение для оценки. Рассматриваемый объект - это MilhouseHour, у которого нет свойства с именем «aspnet_User.UserName».

У вас есть несколько вариантов.

  1. Сделайте то, что вы делали изначально, и сгруппируйте x.aspnet_User вместо x в вашем выражении LINQ. Тогда вещь, повторяемая CheckBoxList, будет IGrouping, которая будет иметь свойства «UserName» и «UserId», которые будут работать.
  2. Избегайте использования CheckBoxList и используйте что-то, что позволит вам более явно контролировать код во внутреннем цикле, например, повторитель:

    <asp:TemplateField HeaderText="Sunday">
    <ItemTemplate>
        <asp:Repeater ID="shiftsSun" runat="server" DataSource='<%#Eval("hourUsers")%>'>
            <ItemTemplate>
                <asp:CheckBox runat="server" 
                   Text='<%# Eval("aspnet_User.UserName")  %>' 
                   Value='<%# Eval("aspnet_User.UserId") %>' />
                <br />
            </ItemTemplate>
        </asp:Repeater>
    </ItemTemplate>
    

Возможно, есть еще много вариантов, но это то, что происходит со мной в данный момент.

1 голос
/ 06 мая 2009

Я не думаю, что вы упускаете какие-либо основные понятия. Групповой запрос создает коллекцию IGrouping, где независимо от типа объектов в коллекции MilhouseHours. (Я не могу получить более полную картину для вашей объектной модели.) Затем вы связываете эти группировки с источником данных CheckBoxList. Вам не хватает директивы DataTextField = "NameField", но нет основных понятий. Вот код, который работает, по крайней мере, связанный с вашей проблемой, если не идентичен:

        <asp:GridView ID="myGrid" runat="server" AutoGenerateColumns="false">
        <Columns>
            <asp:TemplateField>
                <ItemTemplate>
                    <%# Eval("hourUsers.Key") %>
                </ItemTemplate>
            </asp:TemplateField>

            <asp:TemplateField HeaderText="Sunday">
                <ItemTemplate>
                    <asp:CheckBoxList ID="shiftsSun" runat="server" 
                        DataSource='<%#Eval("hourUsers")%>' 
                        DataTextField = "Name"
                        DataValueField = "Id" />
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

А на странице:

    class UserHour
    {
        public string Name {get;set;}
        public int Id { get; set; }
        public string Hour { get; set; }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        var users = new List<UserHour>
                        {
                                    new UserHour {Name = "Fred", Id = 1, Hour = "0800"},
                                    new UserHour {Name = "Fred", Id = 1, Hour = "0900"},
                                    new UserHour {Name = "Fred", Id = 1, Hour = "1000"},
                                    new UserHour {Name = "Bob", Id = 2, Hour = "0900"},
                                    new UserHour {Name = "Bob", Id = 2, Hour = "1000"},
                        };
        var result = from x in users
                     group x by x.Hour
                     into hour select new
                                          {
                                                      hourStr = hour.Key, hourUsers = hour
                                          };

        myGrid.DataSource = result;
        myGrid.DataBind();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...