代码之家  ›  专栏  ›  技术社区  ›  Sisiutl

LINQ到SQL协方差-这是正确的方法吗?

  •  0
  • Sisiutl  · 技术社区  · 16 年前

    我有几个数据库——大象、长颈鹿、大猩猩等——每个数据库都有一个输入和结果表,分别名为ElephantInputs、ElephantResults、长颈鹿输入、长颈鹿结果、大猩猩输入、大猩猩结果。我无法控制表的命名。

    我正在使用LINQtoSQL自动生成ElephantInputs、ElephantResults、GiraffInputs、GiraffResults等类。

    我做的第一件事是为输入和结果对象创建一个接口,并为每个数据库创建一个分部类,以便其输入和结果对象实现该接口。这给了我每种动物一个共同的界面。我还为每个数据库创建了一个repository类,该类具有一些从数据库返回项目的方法。

    public interface IBaseInput
    {
        int ID { get; set; }
        string InputA { get; set; }
        int InputB { get; set; }
        double InputC { get; set; }
    }
    
    public interface IBaseResult
    {
        int ID { get; set; }
        string ResultA { get; set; }
        int ResultB { get; set; }
        double ResultC { get; set; }
    }
    
    public interface IRepository<I, R>
        where I : IBaseInput
        where R : IBaseResult
    {
        IQueryable<I> GetInputs();
        IQueryable<R> GetResults();
    }
    
    public partial class GorillaInput : IBaseInput
    {
    }
    
    public partial class GorillaResult : IBaseResult
    {
    }
    
        // A concrete repository for Gorillas
        public class GorillaRepository : IRepository<GorillaInput, GorillaResult>
        {
    
        GorillaDataContext db = new GorillaDataContext(GetConnectionString("Gorillas"));
    
        public IQueryable<GorillaInput> GetInputs()
        {
            return from p in db.GorillaInputs select p;
        }
    
        public IQueryable<GorillaResult> GetResults()
        {
            return from r in db.GorillaResults select r;
        }
    }
    

    接下来,我为我的处理器创建了一个接口

    public interface IProcessor
    {
        void Process();
    }
    

    这是一个具体的处理器和制造它的工厂。

    public class Processor<T, I, R> : IProcessor
        where T : class, IRepository<I, R>, new()
        where P : IBaseInput
        where R : IBaseResult
    {
    
        public void Process()
        {
            // Do some stuff ...
    
            T repository = new T();  // Get results from the rater tables
            IEnumerable<I> inputs = repository.GetInputs();
            IEnumerable<R> results = repository.GetResults();
    
            // Do some stuff with inputs and outputs...
        }
    }
    
    public static class ProcessorFactory
    {
        public static IProcessor GetProcessor(string animal)
        {
            switch (animal) {
                case "Elephant":
                    return new Processor<ElephantRepository, ElephantInput, ElephantResult>();
                case "Giraffe":
                    return new Processor<GiraffeRepository, GiraffeInput, GiraffeResult>();
                case "Gorilla":
                    return new Processor<GorillaRepository, GorillaInput, GorillaResult>();
                default:
                    return null;
            }
        }
    }
    

    最后,这里是调用处理器的程序:

    class Program
    {
        public static void Main()
        {
            IProcessor processor = ProcessorFactory.GetProcessor("Gorilla");
            processor.Process();
        }
    }
    

    我这样做对吗?有没有不那么复杂的方法?

    1 回复  |  直到 16 年前
        1
  •  2
  •   user1228 user1228    16 年前

    既然所有具体类型都实现了接口,为什么还要麻烦使用泛型呢?

    public class Processor
    {
    
        public void Process(IRepository repository)
        {
            // Do some stuff ...
    
            IEnumerable<IBaseInput> inputs = repository.GetInputs();
            IEnumerable<IBaseResult> results = repository.GetResults();
    
            // Do some stuff with inputs and outputs...
        }
    }