如果我有一个ObjectDataSource设置,如:
<asp:ObjectDataSource
ID="ObjectDataSource1"
runat="server"
DataObjectTypeName="Employee"
InsertMethod="Insert"
UpdateMethod="Update"
DeleteMethod="Select"
TypeName="EmployeeDB">
</asp:ObjectDataSource>
以及使用以下方法的数据/业务对象:
public class EmployeeDB
{
public void Insert(Employee emp)
public int Update(Employee emp)
public bool Delete(int id)
}
如何让objectdatasource将Delete方法与不是Employee对象的参数一起使用?
如果无法做到这一点,推荐的替代架构是什么?
修改
为了澄清,我想在我的数据/业务对象上使用方法签名,如上所示,但是如果我尝试允许使用DataObjectTypeName将Employee对象传递给某些方法,那么我似乎失去了有一些方法只需要一个整数id。
如果我不使用DataObjectTypeName,那么我必须将所有方法参数放在ObjectDataSource中并更改数据/业务对象上的方法以匹配,这似乎是一个糟糕的设计选择,因为当Employee对象改变时我将不得不更新这些方法。 有更好的架构吗?
答案 0 :(得分:1)
这是解决方案,它对我来说是更新操作然后删除比更新更容易:
创建Class以传递参数。 例如:我正在为Usermaster表传递参数:UserMasterDT:
public UserMasterDT(int userid, int roleid, string Firstname, string )
{
this.muserid = userid;
this.mroleid = roleid;
this.mfirstname = Firstname;
this.mlastname = Lastname;
}
//Here set this prop as DUMMY output variable, that u used everywhere to get output value
public int iRecUpdated
{
get { return mrecupdated; }
set { mrecupdated = value; }
}
我将objectdatasource绑定到formview以进行更新uperation.Set objectdatasource如下:
<asp:ObjectDataSource ID="odsUser" runat="server"
TypeName="MMCTaxINTLXMLValidation.UserBLL"
SelectMethod="GetUserRoleByUserId"
DataObjectTypeName="MMCTaxINTLXMLValidation.UserMasterDT"
OldValuesParameterFormatString="original_{0}"
UpdateMethod="UpdateUserWithTransaction" onupdated="odsUser_Updated">
<SelectParameters>
<asp:QueryStringParameter Name="iUId" QueryStringField="UserId" Type="Int32"
DefaultValue="-1" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="UserId" Type="Int32" ConvertEmptyStringToNull="true" />
<asp:Parameter Name="RoleId" Type="Int32" ConvertEmptyStringToNull="true" />
<asp:Parameter Name="Firstname" Type="String" ConvertEmptyStringToNull="true" />
<asp:Parameter Name="Lastname" Type="String" ConvertEmptyStringToNull="true" />
<asp:Parameter Name="BirthDate" Type="String" ConvertEmptyStringToNull="true" />
<asp:Parameter Name="MMCEmail" Type="String" ConvertEmptyStringToNull="true" />
<asp:Parameter Name="Homecontact" Type="String" ConvertEmptyStringToNull="true" />
<asp:Parameter Name="Officecontact" Type="String" ConvertEmptyStringToNull="true" />
<asp:Parameter Name="Cellcontact" Type="String" ConvertEmptyStringToNull="true" />
<asp:Parameter Name="Logon" Type="String" ConvertEmptyStringToNull="true" />
<asp:Parameter Name="Password" Type="String" ConvertEmptyStringToNull="true" />
<asp:Parameter Name="PasswordQ1" Type="String" ConvertEmptyStringToNull="true" />
<asp:Parameter Name="PasswordA1" Type="String" ConvertEmptyStringToNull="true" />
</UpdateParameters>
</asp:ObjectDataSource>
注意此处没有任何输出参数
现在,IN U R BLL在更新方法中,传递并返回UserMasterDT作为输入和输出。不要通过单独的参数和不可接受的参数。写代码如:
此处我正在进入和离开UserMasterDT
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, true)]
public UserMasterDT UpdateUserWithTransaction(UserMasterDT tempuser)
{
int iRecUpdated = -1;
Adapter.BeginTransaction();
try
{
string sFlag = "UpdateUserRole";
int iUserId = tempuser.UserId;
int iRoleId = tempuser.RoleId;
string sFirstname = tempuser.Firstname;
string sLastname = tempuser.Lastname;
int? iReturnData;
//THIS OUT IS FROM MY SQL STORED PROCE NOT WITH OBJECTDATASOURCE OUT PARAMETER. IT HAS NOTHING TO DO WITH OBJECT DATA SOUCE.
Adapter.UpdateUserRole(sFlag,iUserId,iRoleId,sFirstname,sLastname,out iReturnData);
if (iReturnData == 1)
{
iRecUpdated = 1;
this.Adapter.CommitTransaction();
}
else if (iReturnData == null)
iRecUpdated = -1;
//What ever is return, set it back to UserMasterDT's iRecUpdated prop
tempuser.iRecUpdated = iRecUpdated;
return tempuser;
}
catch (Exception ex)
{
if (ex != null)
{
Adapter.RollbackTransaction();
//CustomEX objCUEx = new CustomEX(ex.Message, ex);
ex = null;
iRecUpdated = -1; //-1 : Unexpected Error
//What ever is return, set it back to UserMasterDT's iRecUpdated prop
tempuser.iRecUpdated = iRecUpdated;
return tempuser;
}
}
finally
{
tempuser.iRecUpdated = iRecUpdated;
}
//Return tempuser back
return tempuser;
}
然后在aspx.cs页面中读取UserMasterDT的属性,如下所示:
if (e.Exception == null)
{
UserMasterDT tempuser = (UserMasterDT) e.ReturnValue;
lblMsg.Text = "Record Updated : " + tempuser.iRecUpdated.ToString();
}
我的存储过程是:
set ANSI_NULLS ON
create PROCEDURE [dbo].[UpdateUserRole]
(
@sFlag varchar(50),
@iUserId int,
@iRoleId int,
@sFirstname varchar(50),
@sLastname varchar(50),
@iReturnData int output
)
as
Begin
Declare @errnum as int
Declare @errseverity as int
Declare @errstate as int
Declare @errline as int
Declare @errproc as nvarchar(100)
Declare @errmsg as nvarchar(4000)
-----------------------
if @sFlag = upper('UPDATEUSERROLE')
begin
begin try
begin tran
--Update User Master Table
UPDATE tblUserMaster
SET Firstname = @sFirstname,
Lastname = @sLastname,
WHERE UserId = @iUserId
--Update tblUserRolesTran Table
update tblUserRolesTran
set roleid = @iRoleId
where Userid = @iUserId
commit tran -- If commit tran execute then trancount will decrease by 1
-- Return Flag 1 for update user record and role record
SET @iReturnData = 1
end try
begin catch
IF @@Trancount > 0
-- Get Error Detail In Variable
Select @errnum =@@ERROR,
@errseverity = ERROR_SEVERITY(),
@errstate = ERROR_STATE(),
@errline = ERROR_LINE(),
@errproc = ERROR_PROCEDURE(),
@errmsg = ERROR_MESSAGE()
rollback tran
-- To see print msg, keep raise error on, else these msg will not be printed and dislayed
print '@errnum : ' + ltrim(str(@errnum ))
print '@errseverity : ' + ltrim(str(@errseverity))
print '@errstate : ' + ltrim(str(@errstate))
print '@errline : ' + ltrim(str(@errline))
print '@errproc : ' + @errproc
print '@errmsg : ' + @errmsg
--Raise error doesn't display error message below 50000
--So we have to create custom message and add to error table using sp_addmessage ( so_addmessage is built-in sp)
--In custom error message we have line number and error message
Declare @custerrmsg as nvarchar(4000)
Select @custerrmsg = 'Proc: UpdateUserRole, Line: ' + ltrim(str(@errline)) + ': ' + @errmsg
if (@errnum < 50000)
EXEC SP_ADDMESSAGE @msgnum = 50002, @severity = 16, @msgtext = @custerrmsg, @replace = 'REPLACE'
--After adding custom error message we need to raise error
--Raise error will appear at client (.net application)
RAISERROR(50002,16,1)
end catch
end
set nocount off
End
希望这可以帮助您完成任何您需要做的事情。 sairam
答案 1 :(得分:0)
当你将objectdatasource绑定到一个控件时,你应该能够根据你尝试绑定的数据得到一个 Id (在你的例子中,我会假设是EmployeeId),然后你可以将其设置为删除参数。
在这里查看msdn example。
<asp:objectdatasource
id="ObjectDataSource1"
runat="server"
selectmethod="GetAllEmployees"
deletemethod="DeleteEmployee"
ondeleting="NorthwindEmployeeDeleting"
ondeleted="NorthwindEmployeeDeleted"
typename="Samples.AspNet.CS.EmployeeLogic">
<deleteparameters>
<asp:parameter name="EmpID" type="Int32" />
</deleteparameters>
</asp:objectdatasource>
答案 2 :(得分:0)
您必须从对象数据源声明中删除DataObjectTypeName="Employee"
。此属性获取并设置ObjectDataSource控件用于delete方法中的参数的类的名称。
<asp:ObjectDataSource
ID="ObjectDataSource1"
runat="server"
InsertMethod="Insert"
UpdateMethod="Update"
DeleteMethod="Delete"
TypeName="EmployeeDB">
<deleteparameters>
<asp:parameter name="EmpID" type="Int32" />
</deleteparameters>
</asp:ObjectDataSource>
答案 3 :(得分:0)
即使您按如下方式实施课程:
public class EmployeeDB
{
public Employee Insert(Employee emp)
public Employee Update(Employee emp)
public void Delete(Employee emp)
}
当您尝试删除时,您将只获取绑定到对象上'DataKeys'的字段,例如ID。
*在旁注中,在插入或更新后返回对象允许DataView更新行。
我记得它工作的方式是你可以配置你的ObjectDataSource将参数传递给db层 OR 传递对象,而不是两者的组合。
这意味着可以使用手动配置的参数进行以下操作:
public class EmployeeDB
{
public int Insert(string name, DateTime dob)
public int Update(int id, string name, DateTime dob)
public void Delete(int id)
}
答案 4 :(得分:0)
我不久前使用LinqToSql进行类似的项目。我有两种不同类型的删除方法:
public void DeleteDisconnected(Product original_entity)
{
var db = new RmsConcept2DataContext(base.ConnectionString);
db.Products.Attach(original_entity, false);
db.Products.DeleteOnSubmit(original_entity);
db.SubmitChanges();
}
public void Delete(int ID)
{
var db = new RmsConcept2DataContext(base.ConnectionString);
Product product = db.Products.Single(p => p.ProductID == ID);
// delete children
foreach (Release release in product.Releases)
db.Releases.DeleteOnSubmit(release);
db.Products.DeleteOnSubmit(product);
db.SubmitChanges();
}
..您可以看到DeleteDisconnected
方法旨在接受来自'ObjectDataSource'的整个实体对象。我正在使用
ConflictDetection="CompareAllValues"
..和
OldValuesParameterFormatString="original_{0}"
..对于这种情况的'ObjectDataSource'上的参数,但您可能不需要这样做。我想我仍然可以通过上述方法获得并发异常 - 这是我当时想要的 - 利用LinqToSql内置的冲突检测/并发功能。
您的体系结构取决于您在应用程序的较低层中处理数据等的方式(在问题中您似乎没有提到太多)。传递业务对象而不是作为方法参数的所有字段绝对是更成熟的设计。但偶尔(对于删除函数)只需要int
ID ..但它取决于您的底层实现。
答案 5 :(得分:0)
对象方法签名变量名称必须与对象属性名称完全匹配,并且它将起作用。例如,编辑*也不要忘记DataKeyNames属性
public class EmployeeDB
{
public int ID{get;set;}
public string Name {get;set;}
public ing Age{get;set;}
//both these would work
public void Insert(Employee emp)
public void Insert(string Name,int Age)
//both these would work
public void Update(Employee emp)
public void Update(int ID,string Name,int Age)
//works
public void Delete(Employee emp)
//WONT work
public bool Delete(int empId)
//will work
public void Delete(int ID)
}
<asp:ObjectDataSource
ID="ObjectDataSource1"
runat="server"
DataObjectTypeName="Employee"
InsertMethod="Insert"
UpdateMethod="Update"
DeleteMethod="Select"
TypeName="EmployeeDB"
DataKeyNames="ID">
<DeleteParameters>
<asp:Parameter Name="ID" Type="Int32" />
</DeleteParameters>
</asp:ObjectDataSource>
答案 6 :(得分:0)
得到这个问题希望解决这个确切的困境,并在尝试其他答案提出后,得出结论你只是不能混合方法。你的所有方法(插入,更新,删除)都有:
DataObjectTypeName
属性中指定)或<InsertParameters>
,<UpdateParameters>
或<DeleteParameters>
中指定)。使用单参数版本和Insert
方法仅使用Delete
参数不能使用Int32
方法。当我读到ObjectDataSource
documentation清楚地说:
设置DataObjectTypeName属性和ObjectDataSource时 控件与数据绑定控件相关联,即方法 每个必须由InsertMethod和DeleteMethod属性指定 有一个在。中指定的类型的参数 DataObjectTypeName属性。
唯一的例外可能是Update
方法,它可以有一个或两个参数,具体取决于ConflictDetection
属性,但这是一个完全不同的故事。
我遇到的唯一解决方案是重载Delete
方法来欺骗ObjectDataSource
,并在内部使用Delete
参数调用Int32
方法:
// This method gets called by the ObjectDataSource
public Int32 Delete(MyCustomClass foo)
{
// But internally I call the overloaded method
Delete(foo.Id);
}
public Int32 Delete(Int32 id)
{
// Delete the item
}
答案 7 :(得分:0)
如果使用DataObjectTypeName而不是单独的参数,则您使用的业务对象将起作用。您只需要添加DataKeyNames =“Id”,其中Id是您的绑定控件中的主键字段,如GridView或其他内容。
它将填充您的类型参数,在您的“Employee”类型中,“Id”值可用于删除实体。