4

次のような 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)
}

Employee オブジェクトではないパラメータで Delete メソッドを使用するように objectdatasource を取得するにはどうすればよいですか?

これが不可能な場合、推奨される代替アーキテクチャは何ですか?

編集:

明確にするために、上記のようにデータ/ビジネス オブジェクトでメソッド シグネチャを使用したいのですが、DataObjectTypeName を使用して一部のメソッドに Employee オブジェクトを渡すことを許可しようとすると、いくつかのメソッドを持つことができなくなったようです。たとえば、整数の ID だけを取ります。

DataObjectTypeName を使用しない場合は、すべてのメソッド パラメータを ObjectDataSource に配置し、データ/ビジネス オブジェクトのメソッドを一致するように変更する必要があります。従業員オブジェクトが変更されると、私はしなければならないため、これは悪い設計選択のように思えます。これらの各メソッドを更新します。より良いアーキテクチャはありますか?

4

8 に答える 8

1

ここに解決策があり、更新操作で機能していて、更新よりもはるかに簡単に削除できます:

  1. パラメータを渡すクラスを作成します。例: 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; }
    }
    
  2. 次のように objectdatasource を更新のために formview にバインドしています。

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

    ここには出力パラメータがないことに注意してください

  3. これで、 IN UR BLL update メソッドで、 UserMasterDT を入力と出力として渡し、返します。別のパラメータと OUT 変数を渡さないでください。次のようなコードを記述します。

    ここで UserMasterDT を AS IN と 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'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;
    }
    
  4. 次に、aspx.cs ページで、次のように UserMasterDT のプロパティを読み取ります。

    if (e.Exception == null)
    {
        UserMasterDT tempuser = (UserMasterDT) e.ReturnValue;
        lblMsg.Text = "Record Updated : " + tempuser.iRecUpdated.ToString();
    }
    
  5. 私のストアドプロシージャは次のとおりです。

    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
    

これがあなたがする必要があることを何でも助けてくれることを願っています. サイラム

于 2009-12-03T14:56:56.963 に答える
0

この正確なジレンマを解決することを望んでこの質問に行き、他の回答が提案するものを試した後、メソッドを混在させることはできないという結論に達しました。すべてのメソッド (挿入、更新、削除) に次のいずれかがあります。

  • 単一のカスタム クラス パラメーター (その型はDataObjectTypeName属性で指定されます)、または
  • 各プロパティのパラメータのリスト (各<InsertParameters><UpdateParameters>または内で指定<DeleteParameters>)。

Insert単一パラメーター バージョンをDelete使用するメソッドと、パラメーターのみを使用するメソッドを使用することはできませんInt32。明確に述べられているObjectDataSourceドキュメントを読んだときに、私の調査結果が確認されました。

DataObjectTypeName プロパティが設定され、ObjectDataSource コントロールがデータ バインド コントロールに関連付けられている場合、InsertMethod および DeleteMethod プロパティで指定されたメソッドには、DataObjectTypeName プロパティで指定された型のパラメーターがそれぞれ 1 つ必要です。

唯一の例外はUpdate、プロパティに応じて 1 つまたは 2 つのパラメーターを持つことができるメソッドかもしれませんが、それConflictDetectionはまったく別の話です。

私が得た唯一の解決策は、Deleteメソッドをオーバーロードして をだまし、パラメーターを使用してメソッドをObjectDataSource内部的に呼び出すことでした。DeleteInt32

// 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
}
于 2015-05-27T21:10:24.640 に答える
0

個別のパラメーターの代わりに DataObjectTypeName を使用すると、使用しているビジネス オブジェクトが機能します。DataKeyNames="Id" を追加するだけで、Id は GridView などのバインドされたコントロールの主キー フィールドです。

あなたの場合、エンティティを削除するために使用できる「Id」値を持つ「従業員」タイプのタイプパラメータを入力します。

于 2016-02-15T17:41:40.157 に答える
0

オブジェクト メソッド シグネチャの変数名は、オブジェクト プロパティ名と正確に一致する必要があり、機能します。例 edit* 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>
于 2011-12-22T12:14:21.557 に答える
0

少し前に、これに似たプロジェクトに LinqToSql を使用していました。私は2つの異なるタイプの削除方法を持っていました:

    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' に ..params を追加しますが、そうする必要はないかもしれません。LinqToSqlの組み込みの競合検出/同時実行機能を利用するために、上記のアプローチで削除時に同時実行例外を取得できると思います-これは当時私が望んでいたことです.

アーキテクチャは、アプリの下位レイヤーでデータなどを処理する方法によって異なります (質問ではあまり言及されていないようです)。すべてのフィールドをメソッド パラメーターとして渡すよりも、ビジネス オブジェクトを渡す方が確実に成熟した設計です。ただし、(削除関数の場合) intID のみが必要な場合もありますが、基になる実装によって異なります。

于 2009-06-08T09:37:36.510 に答える
0

次のようにクラスを実装したとしても:

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

ID など、削除しようとすると、オブジェクトに渡された「DataKeys」にバインドされたフィールドのみが取得されます。

*ちなみに、Insert または Update の後にオブジェクトを返すと、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)
}
于 2009-05-28T07:21:24.233 に答える
0

objectdatasource をコントロールにバインドすると、バインドしようとするデータに基づいてId (この例では EmployeeId と仮定します)を取得できるはずです。これを削除パラメーターとして設定できます。

ここでmsdnの例をチェックしてください。

<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>
于 2009-05-27T01:50:04.260 に答える