我有一个类似于下面的类(C#):
public class Product {
public int ID {get;set;}
public string Name {get;set;}
public double Price {get;set;}
public void Save() {
string sql = "INSERT INTO Product.....";
Database.Execute(sql);
}
public void Delete() {
string sql = "DELETE Product WHERE.....";
Database.Execute(sql);
}
}
我主要担心的是上面的代码违反了 SOLID 原则,因为它负责创建和删除自己。
也许这些 Save 和 Delete 方法应该放在 Product 实体之外的某个地方(也许是 Factory/Repository?)。
最佳答案
我将介绍您的模型实体、命令和查询模式以及数据库层或存储库。
你的模型就是你的Product
这个对象应该是一个普通对象:
public class Product : IEntity {
public int ID { get; set; }
public string Name { get; set; }
public double Price { get; set; }
}
接下来我将创建一个命令和查询接口(interface)来处理这个实体:
public interface ICommand {} // Marker interface
public interface IQuery<TResult> {} // Marker interface
接下来为 ICommand
定义处理程序和 IQuery
:
public interface IHandleQuery<TQuery, TResult> where TQuery : IQuery<TResult>
{
TResult Handle(TQuery query);
}
public interface IHandleCommand<TCommand> where TCommand : ICommand
{
void Handle(TCommand command);
}
现在您清楚地指示并分离了写入(命令)和读取(查询)端。
这意味着我们可以创建一个命令及其处理程序来保存您的 Product
喜欢:
public class SaveProduct : ICommand
{
public string Name { get; private set; }
public double Price { get; private set; }
public SaveProduct(string name, double price)
{
Name = name;
Price = price;
}
}
public class HandleSaveProduct : IHandleCommand<SaveProduct>
{
private readonly IRepository<Product> _productRepository;
public HandleSaveProduct(IRepository<Product> productRepository)
{
_productRepository = productRepository;
}
public void Handle(SaveProduct command)
{
var product = new Product {
Name = command.Name,
Price = command.Price
};
_productRepository.Save(product);
}
}
In the above we have defined an repository for handling this entity, you can however depend directly on your database context here and do the queries/commands to it or you can implement the repository pattern using an
GenericRepository<TEntity> : IRepository<TEntity>
or just the separate product repository:
public interface IEntity { } // Marker interface
public interface IRepository<TEntity> where TEntity : IEntity
{
TEntity Get(object primaryKey);
void Save(TEntity entity); // should handle both new and updating entities
void Delete(TEntity entity);
}
public class ProductRepository : IRepository<Product>
{
public Product Get(object primaryKey)
{
// Database method for getting Product
}
public void Save(Product entity)
{
// Database method for saving Product
}
public void Delete(Product entity)
{
// Database method for deleting Product
}
}
你不应该将你的产品实体返回到你的用户界面,而是使用 View 模型,例如:
public class ProductViewModel {
public int ID { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public DateTime Whatever { get; set; }
}
public class GetProductById : IQuery<ProductViewModel>
{
public int Id { get; private set; }
public GetProductById(int id)
{
Id = id;
}
}
public class HandleGetProductById : IHandleQuery<GetProductById, ProductViewModel>
{
private readonly IRepository<Product> _productRepository;
public HandleGetProductById(IRepository<Product> productRepository)
{
_productRepository = productRepository;
}
public ProductViewModel Handle(GetProductById query)
{
var product = _productRepository.Get(query.Id);
return product.Select(x => new ProductViewModel {
Name = x.Name,
Price = x.Price;
});
}
}
请注意,这是用记事本编写的,可能无法 100% 编译,但您应该了解如何分离各种组件以遵循 SOLID。 :-)
关于c# - 将实体保存到数据库的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36899101/