我有两个级联下拉列表,我试图绑定到两个独立的SqlDataSource。
这些下拉列表存在于FormView的EditItemTemplate中。在EditItemTemplate内部,存在两个sqldatasource控件,用于填充部门和作业名称。 DeptID和JobID是这些表中的主键。这会在部门和工作之间产生“级联效应”。选择部门后,仅显示与该部门关联的作业。
这件作品正常运作。
<asp:FormView ID="frmProfile" runat="server" DataSourceID="sqlDSProfile"
DataKeyNames="EUID" style="margin-top: 0px">
<EditItemTemplate>
<asp:DropDownList ID="ddlDepartments" runat="server" Width="135px"
DataSourceID="sqlDSDepartments"
DataTextField="Department"
DataValueField="DeptID" AutoPostBack="True"
SelectedValue='<%# Bind("CurrentDeptID") %>'
AppendDataBoundItems="true" >
<asp:ListItem></asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="ddlJobNames" runat="server" Width="185px"
DataSourceID="sqlDSJobs" DataTextField="JobName" DataValueField="JobID"
SelectedValue='<%# Bind("CurrentJobID") %>'
AppendDataBoundItems="true" >
<asp:ListItem></asp:ListItem>
</asp:DropDownList>
<asp:SqlDataSource ID="sqlDSDepartments" runat="server"
ConnectionString="<%$ ConnectionStrings:JobsDB %>"
SelectCommand="SELECT tblDepartments.DeptID,
tblDepartments.Department
FROM tblDepartments" />
<asp:SqlDataSource ID="sqlDSJobs" runat="server"
ConnectionString="<%$ ConnectionStrings:JobsDB %>"
SelectCommand="SELECT tblJobs.JobID, tblJobs.JobName FROM tblJobs
INNER JOIN tblDeptsJobs ON tblDeptsJobs.JobID = tblJobs.JobID
WHERE tblDeptsJobs.DeptID = @DeptID" >
<SelectParameters>
<asp:ControlParameter ControlID="ddlDepartments" Name="DeptID"
PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
</EditItemTemplate>
</asp:FormView>
在formview之外,存在SqlDataSource,它将所有信息绑定到update语句中的Employee表。我将这个SqlDataSource中的所有其他信息保留下来,即使它已从上面的FormView中省略。
<asp:SqlDataSource ID="sqlDSProfile" runat="server"
ConnectionString="<%$ ConnectionStrings:JobsDB %>"
SelectCommand="SELECT tblEmployee.EUID,
tblEmployee.DateHired,
tblEmployee.LastName,
tblEmployee.HiredLastName,
tblEmployee.FirstName,
tblEmployee.Role,
tblEmployee.JobGrade,
tblEmployee.CurrentDeptID,
tblDepartments.Department,
tblDepartments.DeptID,
tblEmployee.CurrentJobID,
tblJobs.JobName,
tblJobs.JobID,
tblEmployee.CurrentShift,
tblEmployee.JobDate,
tblEmployee.IsDisplaced,
tblEmployee.EligibilityDate
FROM tblEmployee
LEFT OUTER JOIN tblDepartments ON tblEmployee.CurrentDeptID = tblDepartments.DeptID
EFT OUTER JOIN tblJobs ON tblEmployee.CurrentJobID = tblJobs.JobID
WHERE (tblEmployee.EUID = @EUID)"
UpdateCommand="UPDATE [tblEmployee]
SET [tblEmployee].[DateHired] = @DateHired,
[tblEmployee].[LastName] = @LastName,
[tblEmployee].[HiredLastName] = @HiredLastName,
[tblEmployee].[FirstName] = @FirstName,
[tblEmployee].[Role] = @Role,
[tblEmployee].[JobGrade] = @JobGrade,
[tblEmployee].[CurrentDeptID] = @CurrentDeptID,
[tblEmployee].[CurrentJobID] = @CurrentJobID,
[tblEmployee].[CurrentShift] = @CurrentShift,
[tblEmployee].[JobDate] = @JobDate,
[tblEmployee].[IsDisplaced] = @IsDisplaced,
[tblEmployee].[EligibilityDate] = @EligibilityDate
WHERE [tblEmployee].[EUID] = @EUID"
ProviderName="System.Data.SqlClient">
<SelectParameters>
<asp:SessionParameter Name="EUID" SessionField="sProfileEUID" DbType="String" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="DateHired" DbType="Date" />
<asp:Parameter Name="LastName" DbType="String" />
<asp:Parameter Name="HiredLastName" DbType="String" />
<asp:Parameter Name="FirstName" DbType="String" />
<asp:Parameter Name="Role" DbType="String" />
<asp:Parameter Name="JobGrade" DbType="Byte" />
<asp:Parameter Name="CurrentDeptID" DbType="Int32" />
<asp:Parameter Name="CurrentJobID" DbType="Int32" />
<asp:Parameter Name="CurrentShift" DbType="Int32" />
<asp:Parameter Name="JobDate" DbType="Date" />
<asp:Parameter Name="IsDisplaced" DbType="Boolean"/>
<asp:Parameter Name="EligibilityDate" DbType="Date"/>
<asp:SessionParameter Name="EUID" SessionField="sProfileEUID" DbType="String" />
</UpdateParameters>
</asp:SqlDataSource>
我无法弄清楚如何绑定的唯一部分是部门和工作。其他一切都在发挥作用。我尝试在DropDownList控件中使用以下代码...
SelectedValue='<%# Bind("CurrentDeptID") %>'
SelectedValue='<%# Bind("CurrentJobID") %>'
...但这会导致错误。
当用户点击编辑时,我需要两个下拉框中的值从主sqlDSProfile数据源中提取他们的selectedvalue,但我需要它们是可更新的。我已经知道我可以更新并绑定一个员工所属的工作,但由于下拉列表级联,当我尝试更改部门时,AutoPostBack会破坏sqlDSProfile - CurrentJobID和ddlJobs之间的绑定。
我将tblEmployee.CurrentDeptID
和tblEmployee.CurrentJobID
添加到select语句,并将Bind()语句添加到DropDownList控件。
SelectedValue='<%# Bind("CurrentDeptID") %>'
SelectedValue='<%# Bind("CurrentJobID") %>'
现在,两个DropDownLists填充了从Employee表中提取的准确信息,显示了该员工所属的部门和工作。
两个DropDownLists也由FormView中的两个SqlDataSource填充,为我提供了更改部门和更改作业的选项。
当我更改作业时,它会起作用,员工的工作也会更新。
当我更改部门时,会打断DataBinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.
我从ddlJobs中删除了数据绑定,并在后台对其进行了编码。
Protected Sub frmProfile_ItemUpdating(sender As Object, e As System.Web.UI.WebControls.FormViewUpdateEventArgs) Handles frmProfile.ItemUpdating
If frmProfile.CurrentMode = FormViewMode.Edit Then
e.NewValues("CurrentJobID") = DirectCast(DirectCast(sender, FormView).FindControl("ddlJobs"), DropDownList).SelectedValue
End If
End Sub
剩下的唯一部分是构建ddlDepartments更改时的代码。
...伪代码
' If Item exists in ddlJobs Then
' select item (CurrentJobID)
' else
' select index 0 and make them pick something new
' end if
如此接近!
这是我开发的松散绑定的代码。在page_load中,我试图从sqlDSProfile中提取CurrentJobID的内容,并检查ddlJobs中是否存在该值。如果是的话,我想将ddlJobs.SelectedValue =设置为该CurrentJobID。如果不是,我想将selectedindex设置为0,这是一条说“选择一个”的消息。
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If frmProfile.CurrentMode = FormViewMode.Edit Then
' Need to determine if the CurrentJobID returned in the select statement
' exists in the ddlJobs dropdownlist. If it does, set that to the
' selectedvalue, if not set it to 0 so the user can select a new job.
Dim ddlJobs As DropDownList = frmProfile.FindControl("ddlJobs")
Dim dvProfile As DataView = sqlDSProfile.Select(DataSourceSelectArguments.Empty)
Dim drvProfile As DataRowView = dvProfile(0)
If ddlJobs.Items.FindByValue(drvProfile("CurrentJobID")) Is DBNull.Value Then
ddlJobs.SelectedIndex = 0
Else
ddlJobs.SelectedValue = drvProfile("CurrentJobID")
End If
End If
End Sub
它在我正在检查dbnull.value
的行上返回一个空引用异常答案 0 :(得分:4)
我遇到了类似的问题,发现了一个非常简单的解决方案(在c#中)。想象一个带有表格的数据库,与类别和子类别表相关的问题(也是相关和约束的)。当尝试更新现有记录时,asp会抛出错误。这是我通过Lucretius等人提供的上述信息得出的解决方案。
如:
protected void odseditquestion_Updating(object sender, ObjectDataSourceMethodEventArgs e)
{
//dynamically assign value from ddlsubcategory to odseditquestion on updating event
//you really should not have to do this
DropDownList ddlsubcategory = (DropDownList)fveditquestion.FindControl("ddlsubcategory");
e.InputParameters["subcatid"] = (ddlsubcategory.SelectedValue);
}
它适用于我的应用程序。希望它对某人有所帮助,这个花了我半天,这就是asp !!
答案 1 :(得分:2)
问题可能是更新语句中的tlbEmployee
中的SqlDSProfile
列和控件使用的字段名称不匹配。您遵循的其他程序是正确的。
SqlDataSource control expects field names it updates to be similar
with those bound to the controls(fields) inside the DataBound control.
解决方案可以是:将所有更新Parameters
更改为ControlParameter
,为每个更新引用正确的控制权。
更新:等等,我认为问题是您的SqlDSProfile的select语句应该包含:CurrentDeptID
和CurrentJobID
。试试吧:
<asp:SqlDataSource ID="sqlDSProfile" runat="server"
ConnectionString="<%$ ConnectionStrings:JobsDB %>"
SelectCommand="SELECT tblEmployee.EUID,
tblEmployee.DateHired,
tblEmployee.LastName,
tblEmployee.HiredLastName,
tblEmployee.FirstName,
tblEmployee.Role,
tblEmployee.JobGrade,
tblDepartments.Department,
tblJobs.JobName,
tblEmployee.CurrentShift,
tblEmployee.JobDate,
tblEmployee.IsDisplaced,
tblEmployee.EligibilityDate
tblEmployee.CurrentDeptID,
tblEmployee.CurrentJobID
FROM tblEmployee
建议:逐部分测试您的代码。
尝试不带下拉列表的代码,单独测试
添加一个下拉列表
在选择查询中使用select * from ...
测试时避免使用ajax
如果你做到了
在部分之后添加部分代码部分
最后使用部分更新(ajax)
答案 2 :(得分:1)
我现在有一个可行的解决方案,部分归功于Nuux和一系列在线研究。关于join语句的提示是不相关的,但是在我的select查询中包含“CurrentJobID”和“CurrentDeptID”的提示是现货。
除此之外,我还需要稍微修改控件。下面是两个级联下拉列表。 ddlJobs下拉列表的行为类似于普通的数据绑定控件,但它没有我在原始帖子中尝试的Bind(“CurrentJobID”)语句。
<asp:DropDownList ID="ddlDepartments" runat="server" Width="185px"
DataSourceID="sqlDSDepartments"
DataTextField="Department"
DataValueField="DeptID"
SelectedValue='<%# Bind("CurrentDeptID") %>'
AppendDataBoundItems="true"
AutoPostBack="True" >
<asp:ListItem Text="--Select One--" Value="" />
</asp:DropDownList>
<asp:DropDownList ID="ddlJobs" runat="server" Width="185px"
DataSourceID="sqlDSJobs"
DataTextField="JobName"
DataValueField="JobID"
AppendDataBoundItems="true"
OnDataBinding="ddlJobs_DataBinding" />
自定义例程“ddlJobs_DataBinding”正在做的唯一事情是在ddlJobs下拉列表中添加“--Select One--”作为索引0。我在几个地方尝试了这个,比如page_load,以及formview的数据绑定事件没有成功。
Protected Sub ddlJobs_DataBinding(sender As Object, e As System.EventArgs)
Dim ddlJobs As DropDownList = frmProfile.FindControl("ddlJobs")
Dim liSelectOne As New ListItem("--Select One--", 0)
ddlJobs.Items.Clear()
ddlJobs.Items.Insert(0, liSelectOne)
End Sub
formview frmProfile_DataBound事件的数据绑定事件确实做了一些工作。当用户单击窗体视图上的“编辑”以进入编辑模式时,这可确保下拉列表ddlJobs默认情况下为相关配置文件选择了正确的作业。如果用户尚未分配给作业,则默认为选择索引0,即在上面的自定义数据绑定事件中设置的“ - 选择一个 - ”。
Protected Sub frmProfile_DataBound(sender As Object, e As System.EventArgs) Handles frmProfile.DataBound
If frmProfile.CurrentMode = FormViewMode.Edit Then
Dim ddlJobs As DropDownList = frmProfile.FindControl("ddlJobs")
Dim dvProfile As DataView = sqlDSProfile.Select(DataSourceSelectArguments.Empty)
Dim drProfile As DataRow = dvProfile.Table.Rows(0)
If drProfile("CurrentJobID").ToString() = "" Then
ddlJobs.SelectedIndex = 0
Else
ddlJobs.SelectedValue = drProfile("CurrentJobID").ToString()
End If
End If
End Sub
最后,如果用户从ddlJobs中选择一个新作业,则必须将该值输入数据库,即formview处理的ItemUpdating事件。
Protected Sub frmProfile_ItemUpdating(sender As Object, e As System.Web.UI.WebControls.FormViewUpdateEventArgs) Handles frmProfile.ItemUpdating
If frmProfile.CurrentMode = FormViewMode.Edit Then
Dim ddlJobs As DropDownList = frmProfile.FindControl("ddlJobs")
e.NewValues("CurrentJobID") = ddlJobs.SelectedValue
End If
End Sub
完成!