在C#中是否可以像在C / C ++中那样将类类型保存为预处理器指令?
我有多种服务,并且共享了很多代码。主要区别在于调用正确的DbSet
和使用正确的类。
从以下代码到:
public class TaxService
{
readonly DatabaseContext db;
public TaxService(DatabaseContext database)
{
db = database;
}
public async Task<string> DeleteAsync(int? id)
{
if (await db.Taxes.FindAsync(id) is Tax tax)
{
string title = tax.Name;
db.Taxes.Remove(tax);
try
{
await db.SaveChangesAsync();
return title;
}
catch (Exception ex)
{
throw;
}
}
return null;
}
public async Task<List<Tax>> GetAllAsync()
{
return await db.Taxes.AsNoTracking().ToListAsync();
}
}
例如:
public class TaxService<T> where T : Tax
{
readonly DatabaseContext db;
DbSet<Tax> dbSet => db.Tax;
public TaxService(DatabaseContext database)
{
db = database;
}
public async Task<string> DeleteAsync(int? id)
{
if (await dbSet.FindAsync(id) is T tax)
{
string title = tax.Name;
dbSet.Remove(tax);
try
{
await db.SaveChangesAsync();
return title;
}
catch (Exception ex)
{
throw;
}
}
return null;
}
public async Task<List<T>> GetAllAsync()
{
return await dbSet.AsNoTracking().OfType<T>().ToListAsync();
}
}
Ofc上面的设计中有问题。当我尝试调用TaxService
时,我必须通过通用类型=> Tax
TaxService<Tax>
类也在方法GetAllAsync
中,我也必须使用OfType
方法来避免编译器错误。无法将List<Tax>
返回为List<T>
对设计模式有何建议?谢谢
我曾经建立过这样的基本控制器。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
namespace DataAccessLayer.Controllers
{
public class BaseController<TEntity> where TEntity : class, new()
{
public virtual TEntity Get<TContext>(Expression<Func<TEntity, bool>> predicate, TContext context) where TContext : DbContext
{
var item = context.Set<TEntity>().FirstOrDefault(predicate);
return item;
}
public List<TEntity> GetList<TContext>(Expression<Func<TEntity, bool>> predicate, TContext context) where TContext : DbContext
{
var item = context.Set<TEntity>().Where(predicate).ToList();
return item;
}
public IQueryable<TEntity> GetListQueryable<TContext>(Expression<Func<TEntity, bool>> predicate, TContext context) where TContext : DbContext
{
var item = context.Set<TEntity>().Where(predicate);
return item;
}
public List<TEntity> GetAll<TContext>(TContext context) where TContext : DbContext
{
var item = context.Set<TEntity>().ToList();
return item;
}
public IEnumerable<TEntity> GetAllEnumerable<TContext>(TContext context) where TContext : DbContext
{
IEnumerable<TEntity> item = context.Set<TEntity>();
return item;
}
public virtual TEntity Update<TContext>(TEntity input, Expression<Func<TEntity, bool>> predicate, TContext context) where TContext : DbContext
{
if (input == null)
return null;
var existing = context.Set<TEntity>().FirstOrDefault(predicate);
if (existing != null) context.Entry(existing).CurrentValues.SetValues(input);
return existing;
}
public virtual TEntity Insert<TContext>(TEntity input, TContext context) where TContext : DbContext
{
context.Set<TEntity>().Add(input);
return input;
}
}
}
您通过创建像这样的控制器来使用它:
public class TaxcController : BaseController<Tax>
{
}
然后创建一个实例。这样,当需要执行“关闭”操作时,您就有一个控制器或存储库来创建您的重载或独特的方法。
public void dostuff()
{
TaxController taxController = new TaxController();
taxController.Insert(item, context);
}
这在处理由醉酒的程序员急忙建立的数据库时非常有用,因为可以使用遵循相同模式的所有内容,而仍然不能通过控制器使用的所有内容,控制器只是负责“四处寻找”,无论数据库中存在什么异常。
这只是一个PoC,您不必如此精确地做。只是为了让您的点头运行。