使用接口实现CRUD

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)

也就是说,两者CreateUpdate获取您正在更新的对象的副本.所不同的是,Update可以得到keyobj,所以它知道哪些对象它正在改变.Create通常会导致创建密钥,因此您将其作为返回值传回.希望有所帮助.

(更新也可能会传回密钥.)

  • 继承没有意义.您的StudentManager不是学生. (2认同)

Jos*_*ris 9

就个人而言,我认为你所缺少的只是适当的术语.这实际上是一个非常有用的模式的近似,称为存储库模式.就类型感知而言,实现将被称为通用存储库.

我过去亲自实现的方式是有一个定义存储库的接口,例如IRepository<T>,以及特定于存储库类型的基类,例如a SqlRepositoryBase<T>.我这样做的原因是我可以将特定于实现的代码放在基类中.因此,管道完成后,我可以在最终处置库担心特定于域的实现,这将是StudentRepository,一个SqlRepository<Student>(或者SqlRepository<IStudent,如果你定义接口对你的实体>).

您似乎关心有多少对象是实例化的,我可以告诉您,您并没有产生足够的资源消耗来真正关注以这种方式实现.老人可能会对这个事实感到畏缩,但我们不再试图优化64k或RAM了.;-)更多关于可维护性,代码合同等.

不要预先添加不必要的复杂性,但如果您正在寻找将不同类型的多个实体列入原子事务中,您也可能需要查看工作单元模式.

以下是这些主题的几个很好的参考:

一般来说两个要点(恕我直言):

  • 我个人不同意这样的假设:存储库模式方法只对大型项目有用; 特别是Generic Repository模式.如果您开始将这样的代码放入可重用的库中,您会惊讶地发现创建一个宝贵的构建块资源的速度有多快.

  • 这种方法的最大优点是它的可测性; 甚至比可重用性更重要.如果您希望模拟您的存储库以获得任何类型的TDD方法,您可以轻松地完成此操作.这将允许您在整个代码中围绕存储库的用法编写更丰富的测试.