Просмотр сетки данных с помощью LINQ - PullRequest
2 голосов
/ 27 мая 2010

У меня есть две таблицы базы данных, одна для пользователей веб-сайта, содержащая поля "UserID", "Name" и внешний ключ "PageID". А другой с полями «PageID» (здесь первичный ключ) и «Url».

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

Я не уверен, как это сделать, и не могу найти хороших примеров этой конкретной ситуации. Вот что у меня есть:

  <%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="LinqBinding._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>
        Testing LINQ
    </h2>
    <asp:GridView ID="GridView1" runat="server" DataSourceID="LinqDataSourceUsers" AutoGenerateColumns="false">
        <Columns>
            <asp:CommandField ShowSelectButton="True" />
            <asp:BoundField DataField="UserID" HeaderText="UserID" />
            <asp:BoundField DataField="Name" HeaderText="Name" />
            <asp:BoundField DataField="PageID" HeaderText="PageID" />
            <asp:TemplateField HeaderText="Pages">
            <ItemTemplate
                <asp:DropDownList ID="DropDownList1"
                 DataSourceID="LinqDataSourcePages"
                 SelectedValue='<%#Bind("PageID") %>'
                 DataTextField="Url"
                 DataValueField="PageID"
                 runat="server">
                </asp:DropDownList>
            </ItemTemplate>
            </asp:TemplateField>           
        </Columns>
    </asp:GridView>
    <asp:LinqDataSource ID="LinqDataSourcePages" runat="server" 
    ContextTypeName="LinqBinding.UserDataContext" EntityTypeName="" 
        TableName="Pages">
    </asp:LinqDataSource>
    <asp:LinqDataSource ID="LinqDataSourceUsers" runat="server" 
        ContextTypeName="LinqBinding.UserDataContext" EntityTypeName="" 
        TableName="Users">
    </asp:LinqDataSource>
</asp:Content>

Но это работает только при условии, что пользовательская таблица попадает в сетку (это не проблема), и я получаю данные страницы в раскрывающемся списке, но вот проблема: я, конечно, получаю ВСЕ данные страницы в там не только страницы для каждого пользователя в каждой строке. Итак, как мне установить какое-то ограничение «где» в раскрывающемся списке для каждой строки, чтобы показывать только страницы для пользователя в этой строке? (Кроме того, если честно, я не уверен, что правильно понимаю отношения с внешними ключами, потому что я не слишком привык работать с отношениями).

EDIT:

Я думаю, что установил отношения неправильно. Я продолжаю получать сообщение о том, что «Страницы» не существует как свойство объекта User. И я полагаю, что это невозможно, поскольку отношения сейчас являются односторонними. Поэтому я попытался создать отношения «многие ко многим». Опять же, мои знания базы данных немного ограничены, но я добавил так называемую «таблицу соединений» с полями UserID и PageID, как и первичные ключи других таблиц. Я не смог сделать оба этих первичных ключа в соединительной таблице (хотя некоторые из них, как я видел в примерах, похоже, были ... но так как это было невозможно, я догадался, что так быть не должно). Во всяком случае, я создал отношение из каждой таблицы и создал новые классы LINQ из этого.

Но тогда что мне делать? Я установил соединительную таблицу в качестве источника данных Linq, так как я догадался, что мне нужно сделать это для доступа к обеим таблицам, но это не работает. Затем он жалуется, что у этого объекта нет свойства Name. Так как мне получить доступ к связанным таблицам?

(Кстати: вот одна страница, на которую я смотрел, чтобы найти решение: http://www.iaingalloway.com/2015/06/many-to-many-relationships-in-linq-to-sql.html, но прежде всего я не понимаю, как он изменяет код класса "Order" сзади. Я могу только войти в контекст class (я не могу щелкнуть правой кнопкой мыши по классу в режиме конструктора, как он предлагает, и посмотреть код ...), и там, кажется, нет никакого способа обратиться к классу соединения - Order_Details в его случае). .. Я что-то упустил?)

Вот что я имею сейчас с отношением многих ко многим:

 <%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="ManyToMany._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>
        Many to many LINQ
    </h2>
    <asp:GridView ID="GridView1" runat="server" DataSourceID="LinqDataSource1" AutoGenerateColumns="false">
    <Columns>
        <asp:CommandField ShowSelectButton="True" />
        <asp:BoundField DataField="UserID" HeaderText="UserID" />
        <asp:BoundField DataField="Name" HeaderText="Name" />
        <asp:BoundField DataField="PageID" HeaderText="PageID" />
        <asp:TemplateField HeaderText="Pages">
        <ItemTemplate>
            <asp:DropDownList ID="DropDownList1"
             DataSource='<%#Eval("Pages") %>'
             SelectedValue='<%#Bind("PageID") %>'
             DataTextField="Url"
             DataValueField="PageID"
             runat="server">
            </asp:DropDownList>
        </ItemTemplate>
        </asp:TemplateField>           
    </Columns>
</asp:GridView>
    <asp:LinqDataSource ID="LinqDataSource1" runat="server" ContextTypeName="ManyToMany.UserPageDataContext"
        EntityTypeName="" TableName="UserPages">
    </asp:LinqDataSource>
</asp:Content>

Ответы [ 3 ]

1 голос
/ 28 мая 2010

Ну, кажется, я нашел ответ сам. На этой странице объясняются проблемы со связями «многие ко многим» и LINQ: http://blogs.msdn.com/b/mitsu/archive/2007/06/21/how-to-implement-a-many-to-many-relationship-using-linq-to-sql.aspx. Используя эту информацию, я мог бы изменить класс User, чтобы он имел свойство возвращать коллекцию IEnumerable. Я добавил это в класс User (в коде для контекста Linq): `

    public IEnumerable<Page> Pages
    {
        get { return UserPages.Select(u => u.Page); }
    }

Таким образом, у меня может быть отношение многие ко многим, и я могу просто ссылаться на новое свойство Pages в aspx напрямую:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ManyToMany._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="GridView2" runat="server" DataSourceID="LinqDataSourceUsers" AutoGenerateColumns="false">
            <Columns>
                <asp:CommandField ShowSelectButton="True" />
                <asp:BoundField DataField="UserID" HeaderText="UserID" />
                <asp:BoundField DataField="Name" HeaderText="Name" />
                <asp:TemplateField HeaderText="Pages">
                    <ItemTemplate>
                        <asp:DropDownList ID="DropDownList1" DataSource='<%#Eval("Pages") %>' DataTextField="Url"
                            runat="server">
                        </asp:DropDownList>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
        <asp:LinqDataSource ID="LinqDataSourceUsers" runat="server" ContextTypeName="ManyToMany.UserPageDBDataContext"
            TableName="Users">
        </asp:LinqDataSource>
    </div>
    </form>
</body>
</html>

Надеюсь, это поможет кому-то еще, кто боролся с этим, как я!

0 голосов
/ 28 мая 2010

Я сталкивался с подобными ситуациями ранее с ListView и LinqDataSources. Единственное решение, которое я нашел, это установить источник данных для DropDownlist в событиях OnRowCreated или OnRowDatabound.

Вы все еще можете использовать LinqDataSource для своих BoundFields, но я подозреваю, что в этом случае вам может понадобиться сделать TemplateField в коде, приведенном ниже.

Код:

<asp:GridView ID="GridView1" runat="server" OnRowCreated="GridView1_OnRowCreated" DataSourceID="LinqDataSource1" AutoGenerateColumns="false">
<Columns>
    <asp:CommandField ShowSelectButton="True" />
    <asp:BoundField DataField="UserID" HeaderText="UserID" />
    <asp:BoundField DataField="Name" HeaderText="Name" />
    <asp:BoundField DataField="PageID" HeaderText="PageID" />
    <asp:TemplateField HeaderText="Pages">
    <ItemTemplate>
        <asp:DropDownList ID="DropDownList1"
         DataSource='<%#Eval("Pages") %>'
         SelectedValue='<%#Bind("PageID") %>'
         DataTextField="Url"
         DataValueField="PageID"
         runat="server">
        </asp:DropDownList>
    </ItemTemplate>
    </asp:TemplateField>           
</Columns>

C #:

protected void GridView1_OnRowCreated(object sender, EventArgs e)
{
   //Create int variable with the UserId value
   //Create new Linq query to be used as datasource.  must get pages and filter by userid.
   //FindControl DropDownList1
   //use the linq query mentioned in the second comment  as the datasource for DropDownList1
   //DataBind DropDownList1

   //Example: 
int userId = /*get userid logic*/;
var userPages = from t in dc.Pages
                where t.UserId = userId
                select t;
((DropDownList)/*Find drop down list*/).DataSource = userPages;
((DropDownList)/*Find drop down list*/).DataBind()
}
0 голосов
/ 27 мая 2010

Попробуйте связать источник данных DropDownList со свойством Pages вашего пользовательского объекта

<asp:GridView ID="GridView1" runat="server" DataSourceID="LinqDataSourceUsers" AutoGenerateColumns="false">
    <Columns>
        <asp:CommandField ShowSelectButton="True" />
        <asp:BoundField DataField="UserID" HeaderText="UserID" />
        <asp:BoundField DataField="Name" HeaderText="Name" />
        <asp:BoundField DataField="PageID" HeaderText="PageID" />
        <asp:TemplateField HeaderText="Pages">
        <ItemTemplate
            <asp:DropDownList ID="DropDownList1"
             DataSource='<%#Eval("Pages") %>'
             SelectedValue='<%#Bind("PageID") %>'
             DataTextField="Url"
             DataValueField="PageID"
             runat="server">
            </asp:DropDownList>
        </ItemTemplate>
        </asp:TemplateField>           
    </Columns>
</asp:GridView>
...