3

asp.net Web アプリケーションでデータベースと対話するクラスを構築しようとしています。それをどのように設計するかについてあなたの意見が必要です。これは私が考えていることの例です

public class Person
{
    int personId;
    string name;
    string lastName;

    public int PersonId
    {
        get { return personId; }
    }

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public string LastName
    {
        get { return lastName; }
        set { lastName = value; }
    }

    public Person()
    {

    }

    public static void Save(Person p)
    {
        //datalayer here
        //save the person class
    }

    public static Person GetPerson(int person_id)
    {
        //datalayer here
        //get the person from database and return a person class
        Person p = new Person();
        p.personId = 10;
        p.name = "Alex";
        return p;
    }
}

クラスをインスタンス化せずにデータベースメソッドを使用できるように:

Person p = Person.GetPerson(19);
p.Name = "Alex...";
Person.Save(p);

私はあなたの助けに感謝します。

4

4 に答える 4

4

Automaticプライベート フィールドはコード内で同じことを行うため、プロパティを使用します。

Entityのオブジェクトに対して実行できるOperationSaveだと思います。だから私はそれを静的メソッドとして保持しません。あなたの コードをオブジェクトのメソッドとして移動します。だから私はそれをのように呼びます。データをロードするには、クラスのオーバーロード バージョンを使用します。Person SavePersonobj.Save()constructor

public class Person
{
    int personId;      

    public int PersonId
    {
        get { return personId; }
    }    
    public string Name { set;get;}   
    public string LastName { set;get;}        

    public Person() {}

    public Person(int person_id)
    {
        //call to datalayer here
        //get the person from database and return a person class          
        personId = 10;
        Name= "Alex";  // set the public property value here           
    }
    public bool Save()
    {
        //datalayer here
        //save the person class and return
      // true/false /or new ID (change return type)
    }    

}

そして、電話するときは、

Person p = new Person(19);  //get existing person
p.Name = "New Name";
p.Save();

編集:別の (より良い) アプローチは、エンティティ クラスを単純な POCO として保持することです。つまり、データアクセス/BLコードはありません。それは単に次のようになります

public class Person
{
  public int ID { set;get;}
  public string Name { set;get;}
}

またRepository、データ操作を行う があります。したがって、リポジトリには次のようなメソッドがある場合があります

public interface IRepository
{ 
   Person GetPerson(int id);
   bool SavePerson(Person person);
}

これをクラスに実装Interfaceして、データアクセス操作を行うことができます

public class Repository:IRepository
{
  //implementation of your DA methods here
}

これで、このように別のレイヤー(ビジネスレイヤー)から呼び出すことができます

IRepository repo = new Repository();

var person=repo.GetPerson(19);  
person.Name="Updated Name";
repo.Save(person);
于 2012-07-20T17:33:00.990 に答える
1

私は永続性を無視することが好きです:永続性を無視することの利点は何ですか? )

その場合、Save メソッドを別のクラスに移動して、エンティティを永続化する方法に関する情報がエンティティに含まれないようにする必要があります。

于 2012-07-20T19:07:07.057 に答える
1

求めているのは、オブジェクトのファクトリ メソッド パターンと、データ アクセス コードのリポジトリ パターンです。記事ほどうまく説明できないので、代わりに基本的な考え方を説明し、いくつかの例を示します。

目標は、ユーザーとの通信 (UI)、アプリケーション内でのデータの保持と検証 (ビジネス クラス/モデル)、またはデータ永続性の管理 (データアクセス)。これらの領域をきちんと分割しておくと、コードの保守とデバッグ、または並行開発が容易になります。複数の物理マシンにまたがるアーキテクチャを容易にするなど、他の利点もありますが、それは問題の範囲外です。

基本構造:

概念的な進行状況の取得:

UI -> Person Factory -> Person class -> Repository -> Database

コンセプト進行の保存:

UI -> Person class -> Repository -> Database

内部に説明コメントを含む Person クラス構造:

public class Person
{
   // various properties & methods

   // Constructor access is restricted to control how the class gets consumed.
   // All instance management must go through the factories.
   protected Person() { /* stuff */ }

   // Person factory implementation. It's done inside the Person class so that
   // tight control can be kept over constructor access.
   // The factory is what gives you your instances of Person.
   // It has defined inputs and outputs, as well as more descriptive
   // names than constructor overloads, so consumers know what to expect.
   // It's also a place to put scaffolding code, so you can avoid doing 
   // things like setting properties every time you fetch an instance.
   // The factory takes care of all the object initialization and returns
   // an instance that's ready for use.
   public static Person GetPerson(int id)
   {
       Person p = new Person();

       // here you call the repository. It should return either a native
       // data structure like DataReader or DataTable, or a simple DTO class
       // which is then used to populate the properties of Person.
       // the reason for this is to avoid a circular dependency between
       // the repository and Person classes, which will be a compile time error
       // if they're defined in separate libraries
       using(PersonRepository repo = new PersonRepository())
       {
          DataReader dr = repo.GetPerson(id);
          p.FillFromDataReader(dr);
       }

       return p;
   }

   protected void FillFromDataReader(DataReader dr)
   { /* populate properties in here */ }

   // Save should be an instance method, because you need an instance of person
   // in order to save. You don't call the dealership to drive your car,
   // only when you're getting a new one, so the factory doesn't do the saving.
   public void Save()
   {
      // Again, we call the repository here. You can pass a DTO class, or
      // simply pass the necessary properties as parameters
      using(PersonRepository repo = new PersonRepository())
      {
         this.Id = repo.SavePerson(name, address);
      }
   }
}

さて、リポジトリコード:

// This class implements IDisposable for easy control over DB connection resources.
// You could also design and implement an IRepository interface depending on your needs.
public class PersonRepository : IDisposable
{
   private SqlConnection conn;

   public PersonRepository()
   {
      // in here you initialize connection resources
      conn = new SqlConnection("someConnectionString");
   }

   public void IDisposable.Dispose()
   {
      // clean up the connection
      conn.Dispose();
   }

   // The instance methods talk to the database
   public int SavePerson(string name, string address)
   {
      // call your stored procedure (or whatever) and return the new ID
      using(SqlCommand cmd = conn.CreateCommand())
      {
         // stuff
         return (int)cmd.Parameters["myOutputIDParameter"].Value;
      }
   }

   public DataReader GetPerson(int id)
   {
      // call your stored procedure (or whatever) and return the fetched data
      using(SqlCommand cmd = conn.CreateCommand())
      {
         // stuff
         return cmd.ExecuteReader();
      }
   }
}

最後に、UI レベルで行うことは次のとおりです。

Person joe = Person.GetPerson(joeId);
// stuff
joe.Save();
于 2012-07-20T21:05:31.787 に答える
-1

あなたは正しくやっていますが、クラスに自動プロパティを使用することもできます。それはあなたの時間を節約するかもしれません。例えば。

public class Person
{

    public int PersonId { get; set;}    
    public string Name { get; set;}
    public string LastName { get; set;}

    public Person()
    {
    }
}
于 2012-07-20T18:50:48.027 に答える