C#将类类型保存为预处理器

问题描述 投票:0回答:1

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

对设计模式有何建议?谢谢

c# design-patterns preprocessor-directive
1个回答
1
投票

我曾经建立过这样的基本控制器。

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,您不必如此精确地做。只是为了让您的点头运行。

© www.soinside.com 2019 - 2024. All rights reserved.