C# 类别及;方法,这是一个好方法吗?
我正在尝试构建一个与asp.net web应用程序中的数据库交互的类。我需要你对如何设计它的意见,这里有一个我想要的例子C# 类别及;方法,这是一个好方法吗?,c#,asp.net,class,methods,C#,Asp.net,Class,Methods,我正在尝试构建一个与asp.net web应用程序中的数据库交互的类。我需要你对如何设计它的意见,这里有一个我想要的例子 public class Person { int personId; string name; string lastName; public int PersonId { get { return personId; } } public string Name { get
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);
非常感谢您的帮助。使用
自动
程序,因为您的私有字段在代码中也会这样做
我认为,Save
是一个操作,可以在Person
实体的对象上执行。所以我不会把它作为一个静态的方法。我将移动您的保存代码作为Person
对象的方法。因此,我将像obj.Save()
那样调用它。要加载数据,我将使用重载版本的类构造函数
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;}
}
并且有一个存储库
,为您执行数据操作。因此,您的存储库可能有这样的方法
public interface IRepository
{
Person GetPerson(int id);
bool SavePerson(Person person);
}
IRepository repo = new Repository();
var person=repo.GetPerson(19);
person.Name="Updated Name";
repo.Save(person);
您可以在类中实现此接口
,以执行数据访问操作
public class Repository:IRepository
{
//implementation of your DA methods here
}
现在您可以像这样从不同的层(业务层)调用它
public interface IRepository
{
Person GetPerson(int id);
bool SavePerson(Person person);
}
IRepository repo = new Repository();
var person=repo.GetPerson(19);
person.Name="Updated Name";
repo.Save(person);
您做得不错,但也可以为类使用自动属性。这可能会节省你一些时间。
例如
我喜欢坚持无知的东西:)
在这种情况下,您应该将Save方法移动到另一个类中,这样实体就不会包含任何关于如何持久化它的信息。您需要的是对象的,以及数据访问代码的。我无法像文章那样解释它,因此我将回顾基本思想并提供一些示例
目标是将代码库划分为处理一种特定类型问题的层,例如与用户通信(UI)、在应用程序中保存和验证数据(业务类/模型)或管理数据持久性(数据访问)。保持这些区域的整齐划分可以更容易地维护和调试代码或并行开发。还有其他好处,例如促进跨多台物理机器的体系结构,但这超出了问题的范围
基本结构:
获取概念进展:
UI -> Person Factory -> Person class -> Repository -> Database
UI -> Person class -> Repository -> Database
保存概念进展:
UI -> Person Factory -> Person class -> Repository -> Database
UI -> Person class -> Repository -> Database
人员类别结构,内部有解释性注释:
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();
谢谢你的提示;不知怎的,我忘了自动道具-1:使用存储库模式不正确地将持久层靠近UI。@深奥的ScreenName您能解释一下“靠近UI”吗?@Shyju让UI直接调用存储库将模型层(本例中的Person对象)从UI和数据库之间的通信链中移除。删除这一抽象层会使它“更接近”,因为在UI中的数据进入数据库之前,只有一层(存储库),而不是两层(Person类和存储库),所以这违反了模式。从实际的角度来看,您不希望UI能够直接调用持久性代码……我将实体(POCO)和数据访问层作为单独的项目,以便根据需要在不同的项目中使用相同的实体。您所追求的是对象的实体,以及数据访问代码的实体。