使用接口实现CRUD

时间:2010-09-21 15:01:59

标签: 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; }
 }

我创建了一个CRUD接口来抽象对象的操作

public interface IMaintanable<T>
{
   void Create(T obj);
   T Retrieve(string key);
   void Update(string key);
   void Delete(string key);
 }

然后是通过实现接口

来管理实体及其操作的组件
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
    }
}

样本用法

    public void Button_SaveStudent(Event args, object sender)
    {
        Student student = new Student()
        {
           StudentId = "1", StudentName = "Cnillincy"
        }

        new StudentManager().Create(student);   
     }

如您所见,更新方法存在相当大的异常

    public void Update()
    {
        // should update the record in the DB
    }

此方法应该更新对象属性?我应该继承学生吗?

    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()
    }

或者我应该只将Student课程作为学生管理员的属性包含在内?

     public class StudentManager : IMaintainable<Student>
    {
        public Student student { get; private set };

        public void Create() {}
        public void Update() {}
        public void Retrieve() {}
        public void Delete() {}
    }

哪个更合适?接口怎么样?还有其他建议吗? thanks..C

6 个答案:

答案 0 :(得分:15)

您的CRUD界面应该看起来像

public interface IMaintanable<T>
{
    string Create(T obj);
    T Retrieve(string key);
    void Update(T obj);
    void Delete(string key);
}

即,CreateUpdate都会获取您正在更新的对象的副本。区别在于Update可以从key获取obj,因此它知道它正在改变哪个对象。 Create通常会导致创建密钥,因此您将其作为返回值传回。希望有所帮助。

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

答案 1 :(得分:9)

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

我过去亲自实现的方式是拥有一个定义存储库的接口,例如IRepository<T>,以及一个特定于存储库类型的基类,例如SqlRepositoryBase<T> 。我这样做的原因是我可以将特定于实现的代码放在基类中。因此,管道已经完成,我可以担心最终存储库中的特定于域的实现,如StudentRepositorySqlRepository<Student>(或SqlRepository<IStudent&gt;实体)。

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

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

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

总的来说(IMHO)有两个要点:

  • 我个人不同意存储库模式方法仅在大型项目中有用的假设;特别是Generic Repository模式。如果你开始将这样的代码放入一个可重用的库中,你会惊讶于你能够多快地开始创建一个宝贵的构建块资源。

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

答案 2 :(得分:3)

我从Rob Conery那里看到了我真正喜欢的东西。它的强大之处在于您可以传递给方法的参数的灵活性。你的建议不够强大IMO。在这里查看他的MVC入门套件http://mvcstarter.codeplex.com/(在那里称为ISession)。

public interface IMaintainable : IDisposable
    {
       T Single<T>(Expression<Func<T, bool>> expression) where T : class, new();
       System.Linq.IQueryable<T> All<T>() where T : class, new();
       void Add<T>(T item) where T : class, new();
       void Update<T>(T item) where T : class, new();
       void Delete<T>(T item) where T : class, new();
       void Delete<T>(Expression<Func<T, bool>> expression) where T : class, new();
       void DeleteAll<T>() where T : class, IEntity, new();
       void CommitChanges();
    }

答案 3 :(得分:1)

我不会让StudentManager继承Student,我会像我的create方法一样使Update方法无状态,即

public interface IMaintanable<T>
{
  void Create(T obj);
  T Retrieve(string key);
  void Update(T obj);
  void Delete(string key);
}

public void Update(T obj)
{
  // should update the record in the DB
}

答案 4 :(得分:0)

查看最近发布的新Entity Framework 4。它们具有“按惯例代码”模型,允许您轻松地将业务对象直接映射到数据库,而无需担心DAL。

“Gu”有一个great series概述了映射对象的容易程度,甚至在通过它使用的DbContext模型链接到数据库时进行一些简单的修改。

值得注意的是,当前版本是在CTP4,但我预计大部分问题已经在框架中得到解决,并且应该为您提供良好的服务。

答案 5 :(得分:0)

我在这里稍微改变了一下回答:

public interface IMaintanable<T>
{
    Guid Create(T obj);
    T Read(Guid key);
    bool Update(T obj);
    bool Delete(Guid key);
}

此界面基于我的数据库结构。我使用Guids作为主键。