2010-05-27 69 views
2

我有两个数据库表,一个用于网站用户,包含字段“UserID”,“Name”和外键“PageID”。另一个字段为“PageID”(这里是主键)和“Url”。LINQ的数据绑定gridview

我想能够显示两个表中的数据在gridview中的数据,我想用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> 

但到目前为止,因为它得到用户表到gridview的这只作品(这不是一个问题),我也得到了页面数据到下拉列表中,但这里的问题:我当然会获取所有页面数据,而不仅仅是每行用户的页面。那么,如何在每行的下拉列表中放置某种“where”约束以仅显示该行中用户的页面? (另外,老实说,我不确定我是否正确地获得了外键关系,因为我不太习惯与关系合作)。

编辑:

我想我已经建立了关系不正确。我不断收到“页面”不作为用户对象属性存在的消息。我想现在不可能,因为现在的关系是一种方式。所以我试图创造一个多对多的关系。同样,我的数据库知识有点有限,但我添加了一个名为“联结表”的字段UserID和PageID,与其他表的主键相同。虽然我无法在联结表中创建这两个主键(它看起来像有些人在我见过的例子中有过...但由于这是不可能的,所以我猜他们不应该这样做)。无论如何,我从每个表格创建了一个关系,并从中创建了新的LINQ类。

但是我该怎么办?我将联结表设置为Linq数据源,因为我猜想我必须这样做才能访问这两个表,但这不起作用。然后它抱怨该对象上没有Name属性。那么如何访问相关的表?

(顺便说下:这是我寻找的一个寻找解决方案的页面:http://www.iaingalloway.com/2015/06/many-to-many-relationships-in-linq-to-sql.html,但首先我不明白他是如何修改“Order”类的代码隐藏的,我只能进入上下文类(我可以按照他的建议和查看代码,在设计视图中右键单击该类),并且在那里似乎没有任何方法可以引用结点类 - 在他的情况下是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> 

回答

1

嗯,看来我发现自己的答案。本页面解释了多对多关系和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集合的属性。我已将此添加到类用户(在代码隐藏在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

尝试DropDownList的数据源绑定到页面的PR你的用户对象的操作

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

我已经遇到类似的情况之前与ListView和LinqDataSources。我找到的唯一解决方案是在OnRowCreated或OnRowDatabound事件中为DropDownlist设置数据源。

你仍然可以为你的BoundFields使用LinqDataSource,但我怀疑你可能需要在后面的代码中执行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

对,我其实已经有了类似于此的工作(但只使用代码隐藏)。不过,我认为你的意思是在这里使用一对多的关系,对吗?因为否则,我会在上面的编辑中看到我提到的消息,该属性名称在结点对象上不存在。我真的希望它能够在aspx页面中进行绑定,并且我认为它应该用多对多的方式来完成,因为这样做合适吗?用户可以打很多页面,每个页面可以有很多用户... – Anders 2010-05-27 23:28:06

+0

我可能不是很了解你,但看看我的C#部分更新的评论,看看是否可以解决问题。我建议你为每个RowCreated事件的下拉列表创建一个新的linq查询。这有意义吗? – 2010-05-28 00:01:14