我有两个数据库表,一个用于网站用户,包含字段“UserID”,“Name”和外键“PageID”。另一个是“PageID”字段(这里是主键)和“Url”。
我希望能够使用来自两个表的数据在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”约束来仅显示该行中用户的页面? (另外,说实话,我不确定我是否正确得到外键关系,因为我不太习惯于处理关系)。
编辑:
我认为我已经错误地建立了这种关系。我不断收到“Pages”作为User对象上的属性不存在的消息。我想这不可能,因为现在的关系是单向的。所以我试图建立一个多对多的关系。同样,我的数据库知识有点受限,但我添加了一个所谓的“联结表”,其中包含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>
答案 0 :(得分: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集合的属性。我将它添加到User类(在Linq上下文的代码隐藏中):`
public IEnumerable<Page> Pages
{
get { return UserPages.Select(u => u.Page); }
}
这样我可以拥有多对多关系,我可以直接在aspx中引用新的Pages属性:
<%@ 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>
我希望这能帮助那些一直在努力解决这个问题的人!
答案 1 :(得分:0)
尝试将DropDownList DataSource绑定到用户对象的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>
答案 2 :(得分:0)
我之前遇到类似情况的ListView和LinqDataSources。我发现的唯一解决方案是在OnRowCreated或OnRowDatabound事件中设置DropDownlist的数据源。
您仍然可以将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()
}