CSh*_*oob 11 c# architecture crud
使用将用于抽象DAL操作的接口在BL上实现CRUD的最佳方法是什么?我需要你的意见...
这是我的选秀..
映射在数据库表中的数据实体
public class Student
{
public string StudentId { get; set; }
public string StudentName { get; set; }
public Course StudentCourse { get; set; }
}
public class Course
{
public string CourseCode { get; set; }
public string CourseDesc { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个CRUD接口来抽象对象的操作
public interface IMaintanable<T>
{
void Create(T obj);
T Retrieve(string key);
void Update(string key);
void Delete(string key);
}
Run Code Online (Sandbox Code Playgroud)
然后是通过实现接口来管理实体及其操作的组件
public class StudentManager : IMaintainable<Student>
{
public void Create(Student obj)
{
// inserts record in the DB via DAL
}
public Student Retrieve(string userId)
{
// retrieveds record from the DB via DAL
}
public void Update()
{
// should update the record in the DB
}
public void Delete(string userId)
{
// deletes record from the DB
}
}
Run Code Online (Sandbox Code Playgroud)
样品用法
public void Button_SaveStudent(Event args, object sender)
{
Student student = new Student()
{
StudentId = "1", StudentName = "Cnillincy"
}
new StudentManager().Create(student);
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,更新方法存在相当大的异常
public void Update()
{
// should update the record in the DB
}
Run Code Online (Sandbox Code Playgroud)
该方法应该更新对象属性?我应该继承学生吗?
public class StudentManager : Student , IMaintainable<Student>
{
public void Update()
{
//update record via DAL
}
}
public void Button_SaveStudent(Event args, object sender)
{
Student student = new StudentManager();
student.StudentId = "1";
student.StudentName = "Cnillincy"
student.Update()
}
Run Code Online (Sandbox Code Playgroud)
或者我应该将Student类作为学生管理员的属性包含在内?
public class StudentManager : IMaintainable<Student>
{
public Student student { get; private set };
public void Create() {}
public void Update() {}
public void Retrieve() {}
public void Delete() {}
}
Run Code Online (Sandbox Code Playgroud)
哪个更合适?接口怎么样?还有其他建议吗?thanks..C
Lun*_*ore 15
你的CRUD界面应该是这样的
public interface IMaintanable<T>
{
string Create(T obj);
T Retrieve(string key);
void Update(T obj);
void Delete(string key);
}
Run Code Online (Sandbox Code Playgroud)
也就是说,两者Create并Update获取您正在更新的对象的副本.所不同的是,Update可以得到key从obj,所以它知道哪些对象它正在改变.Create通常会导致创建密钥,因此您将其作为返回值传回.希望有所帮助.
(更新也可能会传回密钥.)
就个人而言,我认为你所缺少的只是适当的术语.这实际上是一个非常有用的模式的近似,称为存储库模式.就类型感知而言,实现将被称为通用存储库.
我过去亲自实现的方式是有一个定义存储库的接口,例如IRepository<T>,以及特定于存储库类型的基类,例如a SqlRepositoryBase<T>.我这样做的原因是我可以将特定于实现的代码放在基类中.因此,管道完成后,我可以在最终处置库担心特定于域的实现,这将是StudentRepository,一个SqlRepository<Student>(或者SqlRepository<IStudent,如果你定义接口对你的实体>).
您似乎关心有多少对象是实例化的,我可以告诉您,您并没有产生足够的资源消耗来真正关注以这种方式实现.老人可能会对这个事实感到畏缩,但我们不再试图优化64k或RAM了.;-)更多关于可维护性,代码合同等.
不要预先添加不必要的复杂性,但如果您正在寻找将不同类型的多个实体列入原子事务中,您也可能需要查看工作单元模式.
以下是这些主题的几个很好的参考:
一般来说两个要点(恕我直言):
我个人不同意这样的假设:存储库模式方法只对大型项目有用; 特别是Generic Repository模式.如果您开始将这样的代码放入可重用的库中,您会惊讶地发现创建一个宝贵的构建块资源的速度有多快.
这种方法的最大优点是它的可测性; 甚至比可重用性更重要.如果您希望模拟您的存储库以获得任何类型的TDD方法,您可以轻松地完成此操作.这将允许您在整个代码中围绕存储库的用法编写更丰富的测试.