gpt4 book ai didi

c# - 如何设计数据库接口(interface)

转载 作者:太空狗 更新时间:2023-10-29 20:17:16 27 4
gpt4 key购买 nike

为了提供对我数据库中对象的访问,我为所有团队成员创建了一个接口(interface),可以像这样使用(简化示例):

public interface IDatabase
{
ObservableCollection<Animal> Animals{ get; }
}

我不希望团队访问内部结构,例如数据库上下文或某些 oracle 对象(封装)...

我实现了两个特定的类,用于现实生活和单元测试:

public class TestDatabase : IDatabase
{ }

public class OracleDatabase : IDatabase
{ }

使用一段时间后,团队成员要求的功能越来越多,我不得不在我的界面中添加方法:

public interface IDatabase
{
ObservableCollection<Animal> Animals{ get; }
ObservableCollection<Animal> Animals(Gender gender);
ObservableCollection<Animal> Animals(Gender gender, Race race);
}

一些过滤和排序的东西当然可以由开发人员自己完成,但最好放在数据库中。


我的问题现在我的界面正在爆炸式增长,它每天都有更多的专业功能,它远非稳定而且一直在变化。

我的设计从一开始就存在缺陷吗?

解决该问题的一些想法:

  1. 向所有开发人员公开数据库上下文对象(我认为不好)
  2. 添加一个接受 linq 查询的函数

最佳答案

您正在尝试重新发明 Repository/UnitOfWork 模式,但您做的并不完全正确。

正确的方法应该接近于此:

// shared between repositories
public interface IGenericRepository<T>
{
T CreateNew();

void Delete( T item );
void Update( T item );
void Insert( T item );

IEnumerable<T> FindAll();
T FindOne( int id );
}

// specific repositories
public interface IAnimalRepository : IGenericRepository<Animal>
{
IEnumerable<Animal> FindByNumberOfLegs( int NumberOfLegs );
// ... anything specific follows
}

public interface IHumanRepository : IGenericRepository<Human>
{
IEnumerable<Human> FindByGender( Gender gender );
// ... specific repository logic follows
}

// unit of work - a service for clients
public interface IUnitOfWork : IDisposable
{
IAnimalRepository AnimalRepository { get; }
IHumanRepository HumanRepository { get; }
// .. other repositories follow

void SaveChanges();
}

这样您的服务层就依赖于存储库层,您可以轻松地在实现之间切换,例如用于单元测试。你的客户写

// example code
using ( IUnitOfWork uow = new YourImplementationOfUnitOfWork() )
{
var animals = uow.AnimalRepository.FindByNumberOfLegs( 3 );

var person = uow.HumanRepository.CreateNew();
person.Name = "John";
uow.HumanRepository.Insert( person );

uow.SaveChanges();
}

如果你打算限制方法的数量,你可以稍微修改存储库接口(interface):

// shared between repositories
public interface IGenericRepository<T>
{
T CreateNew();

void Delete( T item );
void Update( T item );
void Insert( T item );

IQueryable<T> Query { get; }
}

这样您的客户就可以使用 LINQ:

// example code
using ( IUnitOfWork uow = new YourImplementationOfUnitOfWork() )
{
var animals = uow.AnimalRepository.Query.Where( a => a.NumberOfLegs == 3 );

var person = uow.HumanRepository.CreateNew();
person.Name = "John";
uow.HumanRepository.Insert( person );

uow.SaveChanges();
}

关于c# - 如何设计数据库接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17994927/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com