1

アプリケーションのメインデータレイヤーにMSEnterpriseLibrary 5.0(データアクセスブロック)を使用しています。

私はOOの基本を理解していますが(はい、私は継続的に学習する必要があります!)、どこで/なぜ/どのように優れたデザインを利用するか、つまりコードを不必要に繰り返さないことなどを理解するよう努めています。それでも、コードを読みやすく、もちろんデバッグできるようにしようとしています。

したがって、最初に、次のクラスとデフォルト/サンプルメソッドがあります:(ps:db / procからの戻り値はXMLです)

public class ajaxget
{
    public enum outputType : int { JSON = 0, XML = 1 }

    public static string getMemberContacts(string sStartsWith, string sEndswith, outputType eOT)
    {
        //  Get the associated members based upon the criteria
        Database db = DatabaseFactory.CreateDatabase("MyDatabase");
        DbCommand cmd = db.GetStoredProcCommand("get_memberContactsXML");
        db.AddInParameter(cmd, "@memberID", DbType.Int64, Convert.ToInt64(sID));
        db.AddInParameter(cmd, "@startsWith1", DbType.String, sStartsWith);
        db.AddInParameter(cmd, "@startsWith2", DbType.String, sEndswith);
        IDataReader dr = db.ExecuteReader(cmd);
        StringBuilder sb = new StringBuilder();
        while (dr.Read())
        {
            sb.Append(dr.GetValue(0));
        }

        //  Clean up
        dr.Close();
        dr.Dispose();
        cmd.Dispose();

        //  What format to return?
        if (eOT == outputType.XML)
        {
            return sb.ToString();
        }
        if (eOT == outputType.JSON)
        {
            XmlDocument xdoc = new XmlDocument();
            xdoc.LoadXml(sb.ToString());
            return JsonConvert.SerializeXmlNode(xdoc);
        }
    }
}

だから..これまでのところかなり基本的です。ここで、「getMemberContacts」メソッドをさらに増やす方法のテンプレートを確立しようとしています。つまり、仮想メソッドである一般的な「get」メソッドを作成し、パラメーターをオーバーライドする必要がありますか?私はこれが非常に改善に聞こえることを知っています、そしてそれはそうです!学習の一部だと思います。

要約すると、もちろん、params / proc名が明らかに異なる「get」メソッドを再利用しようとしていますが、実際の戻り値(この場合はXML、したがって、戻り値を連結するwhile /append部分) XMLブロック)は同じである必要があります。つまり、戻り値をXMLのままにするか、指定されている場合はJSONを返すことができます。

これは非常に基本的なもの/概念だと思いますが、どんなポインタ/アイデアもありがたく受け取られます!

デビッド。

- - 編集 - -

SQLから直接XMLを返さないことについてのコメントに興味があるので、SQL 2008 XMLの部分を示すだけです-繰り返しますが、さまざまな方法で使用するために生データを取得することは良いことですが、私の場合はすべて私のフロントエンドフレームワークの1つはXMLまたはJSONのいずれかを使用しています(ちなみにJSフレームワークは素晴らしいですwww.dhtmlx.comです)。

したがって、SQL2008のプロシージャは次のとおりです。

CREATE PROCEDURE [dbo].[get_messagesForMemberXMLByID]
    @memberID as bigint=null,
    @days as int=-7
AS
BEGIN
    SET NOCOUNT ON;

    /* Setup the starting point (in the past) from when we wish to select the messages */
    Declare @startDate datetime
    set @startDate = DateAdd(d,@days, getdate())

    SELECT inboxID as "@id", convert(varchar(12),messageCreated,13) as messageCreated, convert(varchar(8), messageCreated,108) as messageCreatedTime, subject,message, messageOpened, messageFrom, messageFromID
    FROM bizzbox
    WHERE memberID = @memberID
    AND convert(char(8), messageCreated, 112) BETWEEN convert(char(8), @startDate,112) AND convert(char(8), getdate(), 112)
    ORDER BY messageCreated desc
    FOR XML PATH('row'), ROOT('rows')
END

出力は次のようにプルバックされます:

<rows>
  <row id="1">
    <messageCreated>31 Oct 2010 </messageCreated>
    <messageCreatedTime>21:27:32</messageCreatedTime>
    <subject>Testing 123</subject>
    <message>Wibble Bibble!</message>
    <messageFrom>David</messageFrom>
    <messageFromID>7</messageFromID>
  </row>
</rows>

..これは、フロントエンド用にフォーマットされたデータが必要な方法です。

このメソッドを使用しない理由がわかります。つまり、別のフレームワークを使用したり、たとえばストレートデータテーブルのデータが必要な場合はどうなりますか。XMLまたはストレート表形式で出力するparam変数を使用できると思います。またはあえて2つのprocを言っても..しかし、どちらの方法でもコメントを聞くことに興味があります...

すべての入力に再度感謝します-それは本当に非常にありがたいです。

4

2 に答える 2

1

これはかなり複雑な質問であるため、これに対する答えは多種多様です。まず、あなたは学習段階にあるので...

  1. メソッド、パラメーター、変数などの名前については、C#の規則に従ってください。また、本当に必要な場合を除いて、ハンガリアン記法を使用しないでください(ハンガリアン記法を使用できるが、使用している場所では使用できないエッジケースがいくつかあります。
  2. 列挙型を使用する場合は、if-elseの代わりにSwitchステートメントを使用してください。
  3. 上記の命名規則にも属していますが、これを個別に強調表示すると思いました。列挙型の値は、XMLとJSONではなく.Xmlと.Jsonである必要があります。

いくつか質問があります:1。なぜXmlを使用しているのですか?2.メンバーの連絡先を保持するデータベーステーブルに、メンバーの連絡先の属性を表す「フィールド」がないのはなぜですか。

「get」メソッドの再利用に関する質問の1つに答えるには、パラメータのタイプと数が常に変化するため、getごとに個別のメソッドを用意することはありません。これらのメソッド内に、すべての「get」メソッドが使用できるプライベートメソッドとして作成された共通の機能がある場合がありますが、各メソッド自体は分離する必要があります。これは、パブリック(または内部)APIを持つデータアクセスクラスを確認する必要があるためです。つまり、このクラスのパブリックメソッドを見ると、このクラスが実行できることと、それを実行するために必要なパラメーターをよく理解する必要があります。ジェネリックメソッドが1つあると、四角いペグを丸い穴に合わせようとするフープを通過するだけでなく、パブリックメソッドを見ると、どの機能が提供されるのかわかりません。

GetMemberContactsメソッドには、次の署名が必要です

public static List<MemberContact> GetMemberContacts(int memberId)

したがって、特定のメンバーの連絡先を取得するには、そのメンバーのIDをパラメーターとして渡す必要があります。このメソッドは、MembercontactまたはDataTabl/DataSetのリストを返す可能性があります。

Xmlが必要な場合、ビジネスレイヤーはそのデータを取得してxmlに変換できます。必要に応じて、同じリストを使用してJsonに変換できます。ビジネスレイヤーに決定させるか、さらに良い方法として、特定のメンバーの連絡先を3つの異なる方法(Aリスト、Json、Xml)で返す3つのメソッドを持たせます。

コードにsStartWithとsEndWithが含まれているのかわからない。つまり、インテントを正しく示す、より適切なメソッド名とより適切なパラメーター名が必要です。

于 2010-11-15T03:22:27.667 に答える
1

まず、手動で物を処分するのではなく、 using構文を使用する必要があります。IDisposableを実装するものなら何でもusing構文を使用できます。

StringBuilder sb = new StringBuilder(); 

using(DbCommand cmd = db.GetStoredProcCommand("get_memberContactsXML"))
{
    db.AddInParameter(cmd, "@memberID", DbType.Int64, Convert.ToInt64(sID)); 
    db.AddInParameter(cmd, "@startsWith1", DbType.String, sStartsWith); 
    db.AddInParameter(cmd, "@startsWith2", DbType.String, sEndswith); 
    using(IDataReader dr = db.ExecuteReader(cmd))
    { 
        while (dr.Read()) 
        { 
            sb.Append(dr.GetValue(0)); 
        } 
    }
}

usingステートメントの利点(簡潔で読みやすく、一般的にすばらしいことに加えて)は、例外が発生した場合でもリソースが確実に破棄されることです。この例では、db.ExecuteReader(cmd)の呼び出しからの例外により、コマンドが破棄されませんでした。

ShivKumarもいくつかの非常に良い点を指摘しています。私はこのようなことをします:

public abstract class DataAccessLayerBase
{
    protected string GetXml(string storedProcedureName, OutputType outputType, params Tuple<string,DBType,object>[] parameters)
    {
        StringBuilder sb = new StringBuilder();

        //  Get the associated members based upon the criteria  
        Database db = DatabaseFactory.CreateDatabase("MyDatabase");  

        using(DbCommand cmd = db.GetStoredProcCommand(storedProcedureName))
        {
            foreach(var parameter in parameters)
            {
                db.AddInParameter(cmd, parameter.Item1, parameter.Item2, parameter.Item3);
            }

            using(IDataReader dr = db.ExecuteReader(cmd))
            {
                while (dr.Read())  
                {  
                    sb.Append(dr.GetValue(0));  
                }  
            }      

            switch(outputType)
            {
                case OutputType.Xml:
                    return sb.ToString();  
                case OutputType.Json:
                    XmlDocument xdoc = new XmlDocument();  
                    xdoc.LoadXml(sb.ToString());  
                    return JsonConvert.SerializeXmlNode(xdoc);  
                default:
                    throw new NotSupportedException(); // Some sort of error.
            }
        }
    } 
}

次に、機能領域ごとにサブクラスを作成します。

public class MemberContactsDal : DataAccessLayerBase
{
    public string GetMemberContacts(long memberID, string startsWith, string endsWith, OutputType outputType)
    {
        // Call the method in the base class to handle all of the parsing.
        return GetXml(
            "get_memberContactsXML", 
            outputType, 
            new Tuple("@memberID", DBType.Int64, memberID ), 
            new Tuple("@startsWith1", DBType.String, startsWith), 
            new Tuple("@startsWith2", DBType.String, endsWith)
        );
    }
}

ただし、ストアドプロシージャがXMLを返している場合は、ストアドプロシージャで何か疑わしいことが起こっているように聞こえます...

私の例がお役に立てば幸いです。私はそれをコンパイルしようとはしていませんが、それはほぼ正しいはずです。

于 2010-11-15T03:53:30.617 に答える