C# 使用ObjectDataSource和DataObjectTypeName,如何仅使用Id参数处理Delete方法?

C# 使用ObjectDataSource和DataObjectTypeName,如何仅使用Id参数处理Delete方法?,c#,.net,asp.net,vb.net,objectdatasource,C#,.net,Asp.net,Vb.net,Objectdatasource,如果我有如下ObjectDataSource设置: <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DataObjectTypeName="Employee" InsertMethod="Insert" UpdateMethod="Update" DeleteMethod="Select" TypeName="EmployeeDB"> </a

如果我有如下ObjectDataSource设置:

<asp:ObjectDataSource 
    ID="ObjectDataSource1" 
    runat="server" 
    DataObjectTypeName="Employee"
    InsertMethod="Insert" 
    UpdateMethod="Update"
    DeleteMethod="Select" 
    TypeName="EmployeeDB">
</asp:ObjectDataSource>
如何使objectdatasource对参数不是Employee对象的参数使用Delete方法

如果不可能,建议的替代体系结构是什么

编辑:

为了澄清,我想在我的数据/业务对象上使用如上所示的方法签名,但是,如果我试图允许使用DataObjectTypeName将Employee对象传递到某些方法中,那么我似乎失去了让某些方法仅取整数id的能力

如果我不使用DataObjectTypeName,那么我必须将所有方法参数放在ObjectDataSource中,并更改数据/业务对象上的方法以匹配,这似乎是一个糟糕的设计选择,因为随着Employee对象的更改,我将不得不更新这些方法中的每一个。
有更好的体系结构吗?

当您将objectdatasource绑定到控件时,您应该能够基于您尝试绑定到的数据获取Id(在您的示例中,我假设EmployeeId),然后您可以将其设置为删除参数

在这里结账


您必须从对象数据源声明中删除
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>

即使您实现了如下类:

public class EmployeeDB
{
    public Employee Insert(Employee emp)
    public Employee Update(Employee emp)
    public void Delete(Employee emp)
}
当您尝试删除时,您将仅获取绑定到对象上传递的字段,例如ID

*另一方面,插入或更新后返回对象允许DataView更新行

我记得它的工作方式是,您可以配置ObjectDataSource,将参数传递到db层传递对象,而不是两者的组合

这意味着,通过手动配置的参数,可以实现以下功能:

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

不久前,我在一个类似的项目中使用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"
…及

…参数,但您可能不需要这样做。我认为我仍然可以使用上述方法(这是我当时想要的)在删除时获得并发异常,以利用LinqToSql内置的冲突检测/并发特性


您的体系结构取决于您如何处理应用程序较低层中的数据等(您在问题中似乎没有提到太多)。将业务对象而不是所有字段作为方法参数进行传递显然是更成熟的设计。但有时(对于删除函数),只需要
int
ID。。但这取决于您的底层实现。

这是一个解决方案,它适用于我的更新操作,然后删除要比更新简单得多:

  • 创建要传递参数的类。 例如:我正在传递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以进行更新更新。按如下方式设置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>
    
    if (e.Exception == null)
    {
        UserMasterDT tempuser = (UserMasterDT) e.ReturnValue;
        lblMsg.Text = "Record Updated : " + tempuser.iRecUpdated.ToString();
    }
    
  • 然后在aspx.cs页面中读取UserMasterDT的属性,如下所示:

    <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>
    
    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
    
    将ANSI_空值设置为ON
    创建过程[dbo]。[UpdateUserRole]
    (
    @sFlag varchar(50),
    @iUserId int,
    @iRoleId int,
    @sFirstname varchar(50),
    @sLastname varchar(50),
    @iReturnData int输出
    )
    作为
    开始
    将@errnum声明为int
    将@errseverity声明为int
    将@errstate声明为int
    将@errline声明为int
    将@errproc声明为nvarchar(100)
    将@errmsg声明为nvarchar(4000)
    -----------------------
    如果@sFlag=upper('UPDATEUSERROLE')
    开始
    开始尝试
    开始事务
    --更新用户主表
    更新tblUserMaster
    SET Firstname=@sFirstname,
    Lastname=@sLastname,
    其中UserId=@iUserId
    --更新tblUserRolesTran表
    更新tblUserRolesTran
    set roleid=@iRoleId
    其中Userid=@iUserId
    commit tran——如果执行commit tran,则trancount将减少1
    --更新用户记录和角色记录的返回标志1
    设置@iReturnData=1
    结束尝试
    开始捕捉
    如果@Trancount>0
    --获取变量中的错误详细信息
    选择@errnum=@@ERROR,
    @errseverity=错误\u严重性(),
    @errstate=ERROR\u STATE(),
    @errline=ERROR\u LINE(),
    @errproc=ERROR\u PROCEDURE(),
    @errmsg=错误消息()
    回滚传输
    --要查看打印消息,请保持raise error on,否则将不会打印和显示这些消息
    打印“@errnum:”+ltrim(str(@errnum))
    打印“@errseverity:”+ltrim(str(@errseverity))
    打印“@errstate:”+ltrim(str(@errstate))
    打印“@errline:”+ltrim(str(@errline))
    打印“@errproc:”+@errproc
    打印“@errmsg:”+@errmsg
    --Raise error在50000以下不显示错误消息
    --因此,我们必须创建自定义消息,并使用sp_addmessage将其添加到错误表中(因此,sp_addmessage是内置的)
    --在自定义错误消息中,我们有行号和错误消息
    声明@custerrmsg为nvarchar(4000)
    选择@custerrmsg='Proc:UpdateUserRole,行:'+ltrim(str(@errline))+
    
    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
    
    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>
    
    // 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
    }