使用接口实现 CRUD

发布于 2024-09-24 11:49:06 字数 2341 浏览 2 评论 0原文

使用将用于抽象 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);   
     }

来管理实体及其操作 的组件可以看到,update方法有相当大的异常,

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

哪个更合适?界面怎么样?大家还有其他建议吗?谢谢..C

What is the best approach to implement a CRUD on the BL using interface that will be used to abstract DAL operations? I need your opinion guys..

Here's my draft..

Data Entities that are mapped in the database table

 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; }
 }

I created an CRUD Interface to abstract the object's operations

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

And then a component that manages the Entity and its operations by implementing the interface

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

sample usage

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

        new StudentManager().Create(student);   
     }

as you can see, there is quite an abnormalities on the update method

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

what should this method have to update the objects property? should I inherit the Student?

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

Or should I just contain the Student class as an attribute of the Student manager?

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

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

Which more appropriate? What about the interface? Any other suggestions guys? thanks..C

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

清风不识月 2024-10-01 11:49:06

您的 CRUD 界面可能看起来像

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

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

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

Your CRUD interface should probably look like

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

that is, both Create and Update take a copy of the object you're updating. The difference is that the Update can get the key from the obj, so it knows which object it's changing. Create would normally cause the key to be created so you pass it back as a return value. Hope that helps.

(The Update might also pass back the key too.)

神回复 2024-10-01 11:49:06

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

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

看来您关心有多少对象被实例化,我可以告诉您,您没有消耗足够多的资源来真正关心以这种方式实现。老前辈可能会对此感到畏缩,但我们不再尝试针对 64k 或 RAM 进行优化。 ;-) 它更多的是关于可维护性、代码契约等。

不要预先添加不必要的复杂性,但如果您正在考虑将不同类型的多个实体纳入原子事务中,您可能还需要研究工作单元模式。

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

一般而言,有两个要点(恕我直言):

  • 我个人不同意存储库模式方法仅在大型项目中有用的假设;特别是通用存储库模式。如果您开始将这样的代码放入可重用库中,您会惊讶地发现您可以如此快速地开始创建宝贵的构建块资源。

  • 这种方法的最大优点是其纯粹的可测试性;甚至比可重用性更重要。如果您希望模拟任何类型的 TDD 方法的存储库,您可以毫不费力地做到这一点。这将允许您围绕整个代码中存储库的使用编写更丰富的测试。

Personally, I think that all you are missing is the appropriate terminology. What this really is an approximation of a very helpful pattern, called the repository pattern. As far as type-awareness, goes, the implementation would be referred to as a generic repository.

The way I have personally implemented in the past was to have an interface defining the repository, such as IRepository<T>, and a base class that is specific to the type of repository, such as a SqlRepositoryBase<T>. The reason that I would do this is that I can put the implementation-specific code in the base class. So, the plumbing is done and I can worry about domain-specific implementation in the final repository, which would be StudentRepository, a SqlRepository<Student> (or SqlRepository<IStudent> if you define interfaces for your entity).

It seems that you are concerned about how many objects are instansiated, and I can tell you that you are not generating a significant enough drain on resources to really be concerned about implementing in this fashion. Old-timers might cringe at the fact, but we are not trying to optimize for 64k or RAM anymore. ;-) It is more about maintainability, code contracts, etc.

Not to add uneeded complexity up-front, but you also might want to look into the Unit of Work Pattern if you are looking at enlisting multiple entities of different types into atomic transactions.

Here are a couple of good references for these topics:

Two takeaways from this in general (IMHO):

  • I personally disagree with the assumption that a Repository pattern approach only has usefulness in larger projects; especially the Generic Repository pattern. If you start putting code like this into a reusable library, you will be surprised at how quickly you can start creating an invaluable resource of building blocks.

  • The biggest plus from this approach is the sheer testability of it; even more so than the reusability. If you are looking to mock out your repositories for any sort of a TDD approach, you can do so with little effort. This will allow you to write richer tests around the usages of the repositories throughout your code.

白鸥掠海 2024-10-01 11:49:06

我从 Rob Conery 那里看到了这个,我非常喜欢。它的强大之处在于您可以传递给方法的参数的灵活性。在我看来,你的实现不够强大。在这里查看他的 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();
    }

I saw this from Rob Conery that I really like. It's power is in the flexibility of the arguments you can pass to the methods. Your implimentation isn't robust enough IMO. Check out his MVC starter kit here http://mvcstarter.codeplex.com/ (It's called ISession there).

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();
    }
老娘不死你永远是小三 2024-10-01 11:49:06

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

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
}

I wouldn't make StudentManager inherit Student, I would make my Update method stateless like your create method, i.e.

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

and

public void Update(T obj)
{
  // should update the record in the DB
}
呆° 2024-10-01 11:49:06

查看最近发布的新Entity Framework 4。它们采用“代码约定”模型,使您可以轻松地将业务对象直接映射到数据库,而不必担心 DAL。

“The Gu”有一个 伟大的系列概述了映射对象是多么容易,甚至在通过它使用的 DbContext 模型链接到数据库时进行一些简单的修改。

值得注意的是,当前版本是 CTP4,但我预计大多数问题已经通过框架得到解决,应该可以很好地为您服务。

Take a look at the new Entity Framework 4 that was recently released. They are featuring a "code by convention" model that allows you to easily map your business objects directly to the database without having to worry about a DAL.

"The Gu" has a great series outlining how easy it is to map your objects, and even do some simple modifications when linking to the database through the DbContext model it uses.

It is worth noting that the current release is at CTP4, but I anticipate most of the issues have already been worked out with the framework and should serve you well.

空名 2024-10-01 11:49:06

我将此处的响应稍微更改为:

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

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

I changed the responses here a little bit, to this:

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

This interface is based on my database structure. I use Guids for primary keys.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文