Using ObjectDataSource and DataObjectTypeName, how do you handle delete methods with just the Id parameter?

If I have an ObjectDataSource setting, for example:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DataObjectTypeName="Employee" InsertMethod="Insert" UpdateMethod="Update" DeleteMethod="Select" TypeName="EmployeeDB"> </asp:ObjectDataSource> 

and a data / business object with methods such as:

 public class EmployeeDB { public void Insert(Employee emp) public int Update(Employee emp) public bool Delete(int id) } 

How do I get an objectdatasource to use the Delete method with a parameter that is not an Employee object?

If this is not possible, then what is the recommended alternative architecture?

Edit:

To clarify, I want to use the method signature on my data / business object, as shown above, however, if I try to allow the Employee object to be passed to some of the methods using DataObjectTypeName, then I apparently lose the ability, for example, some methods accept only integer identifier.

If I do not use the name DataObjectTypeName, then I have to put all the method parameters in an ObjectDataSource and change the methods on the data / business object to fit, this seems like a wrong design choice, because when changing the Employee object I will have to update each of these methods. Is there a better architecture?

+4
source share
8 answers

Here is the solution, and it works for me for the update operation, and then deletes it much easier than updating:

  • Create a class to pass the parameter. For example: I pass a parameter to the Usermaster table: 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; } } 
  • I bind objectdatasource to formview to update update.Set objectdatasource as follows:

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

    NOTICE NO ANY OUTPUT PARAMETER HERE

  • Now, IN UR BLL In the update method, pass and return UserMasterDT as input and output. DO NOT MISS THE APPROPRIATE OPTION AND IMPOSSIBLE. Write the code:

    HERE I PURCHASE UserMasterDT AS IN AND OUT

     [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 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 iRecUpdated prop tempuser.iRecUpdated = iRecUpdated; return tempuser; } } finally { tempuser.iRecUpdated = iRecUpdated; } //Return tempuser back return tempuser; } 
  • then in aspx.cs read the property of the UserMasterDT page as follows:

     if (e.Exception == null) { UserMasterDT tempuser = (UserMasterDT) e.ReturnValue; lblMsg.Text = "Record Updated : " + tempuser.iRecUpdated.ToString(); } 
  • My saved procedure:

     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 

Hope this helps you what you need to do. Saram

+1
source

When you bind an objectdatasource to a control, you can get an Id (in your example I would take an EmployeeId) based on the data you are trying to bind to, and then you can set this as a delete parameter.

check out the msdn example here.

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

You need to remove DataObjectTypeName="Employee" from the object data source declaration. This property receives and sets the name of the class that the ObjectDataSource control uses for the parameter in your delete method.

  <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" InsertMethod="Insert" UpdateMethod="Update" DeleteMethod="Delete" TypeName="EmployeeDB"> <deleteparameters> <asp:parameter name="EmpID" type="Int32" /> </deleteparameters> </asp:ObjectDataSource> 
0
source

Even if you implement your class as follows:

 public class EmployeeDB { public Employee Insert(Employee emp) public Employee Update(Employee emp) public void Delete(Employee emp) } 

You will only get fields bound to 'DataKeys' passed on the object when you try to delete, for example, an identifier.

* On a side note, returning an object after an insert or update, allows the DataView to update the row.

As I recall how this works, you can configure your ObjectDataSource object to pass parameters to your db OR level, although the objects, not their combination.

This means that with manually configured options:

 public class EmployeeDB { public int Insert(string name, DateTime dob) public int Update(int id, string name, DateTime dob) public void Delete(int id) } 
0
source

I used LinqToSql for a project like this recently. I had two different types of removal methods:

  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(); } 

.. you can see that the DeleteDisconnected method DeleteDisconnected designed to accept the entire entity object from the ObjectDataSource object. I used

 ConflictDetection="CompareAllValues" 

.. and

 OldValuesParameterFormatString="original_{0}" 

.. params in an ObjectDataSource for this case, but you may not need to. I think that I could still get concurrency exceptions when deleting using the above approach - that is exactly what I wanted at the time - to use LinqToSql built-in to the conflict detection / concurrency functions.

Your architecture depends on how you process the data, etc. in the lower layers of your application (which you don’t talk much about in the question). Definitely a more mature design allows you to transfer business objects, and not all fields, as method parameters. But sometimes (for delete functions) only the int identifier is required .. but it depends on your base implementation.

0
source

The names of the object object's signature variables must exactly match the object object names, and they will work. for example, edit * also do not forget the DataKeyNames attribute

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

I posed this question, hoping to solve this exact dilemma, and, having tried that they offer other answers, I came to the conclusion that you simply CANNOT mix methods . Or all your methods (Insert, Update, Delete) have:

  • one parameter of the user class (the type of which is specified in the DataObjectTypeName attribute) or
  • a list of parameters for each of the properties (specified in each <InsertParameters> , <UpdateParameters> or <DeleteParameters> ).

You cannot have an Insert method using a single version of a parameter and a Delete method using only the Int32 parameter. My results were confirmed when I read the ObjectDataSource documentation, which clearly states:

When the DataObjectTypeName property is set and the ObjectDataSource control object is associated with data control, the methods that are specified by the InsertMethod and DeleteMethod properties must have one type parameter that is specified in the DataObjectTypeName property.

The only exception may be the Update method, which may have one or two parameters depending on the ConflictDetection property, but this is a completely different story.

The only solution I came across was to overload the Delete method to trick ObjectDataSource and internally call my Delete method with Int32 parameter:

 // 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 } 
0
source

If you use DataObjectTypeName instead of separate parameters, the working business object that you use will work. You just need to add DataKeyNames = "Id", where Id is the primary key field in the Bound control, such as a GridView or something else.

It will populate your type parameter, in your case the type is "Employee" with "Id", which you can use to delete the object.

0
source

All Articles