Лучшая практика в приложениях с несколькими базами данных Entity Framework

Я новичок в программировании на C# и ищу способ сделать несколько обобщений, чтобы лучше работать с Entity Framework, используя несколько баз данных.

Мое приложение было построено с использованием только Oracle Database, используя все сущности внутри моего приложения. Теперь у нас есть необходимость реализовать SQl Server и MySQL в этом приложении.

Для этого я сделал следующие шаги:

  • Удалены все сущности из моего основного приложения;
  • Создано 3 библиотеки классов, по одной для каждой базы данных, содержащей только модели и сгенерированные EF классы;
  • Создана библиотека 4-го класса, содержащая общие классы, которые должны быть заполнены объектами каждой базы данных.

Эта "универсальная" библиотека классов содержит следующие элементы для каждой таблицы:

  • Класс с одинаковым именем таблицы и одинаковыми полями (все базы данных имеют одинаковые имена таблиц и полей);
  • Интерфейс, который реализует базовые методы;
  • Абстрактный класс, который реализует методы интерфейса;
  • Класс, который наследуется от моего абстрактного класса для каждой базы данных;
  • Класс фабрики, который создает требуемый класс базы данных, используя перечисление типа базы данных.

Ниже я привожу пример, используя мою таблицу устройств:

Пример кода

namespace MyApp.Data
{
    internal interface IDevicesDAO
    {
        IEnumerable<Device> GetDevices();
        IEnumerable<Device> GetDevices(int serverId);
        Device GetDeviceById(int deviceId);
    }

    public abstract class DeviceDAO: IDevicesDAO
    {
        public abstract IEnumerable<Business.Device> GetDevices();
        public abstract IEnumerable<Business.Device> GetDevices(int serverId);
        public abstract Business.Device GetDeviceById(int deviceId);

        protected  abstract IEnumerable<Business.Device> ListDevice(int code);
    }

    internal static class DeviceDAO_Factory
    {
        public static DeviceDAO Create(DatabaseTypeEnum databaseType)
        {
            switch (databaseType)
            {
                case DatabaseTypeEnum.Oracle:
                    return new DeviceDAO_Oracle();

                default:
                    return null;
            }
        }
    }

    class DeviceDAO_Oracle: DeviceDAO
    {
        public override IEnumerable<Device> GetDevices()
        {
            return ListDevice(0);
        }

        public override IEnumerable<Device> GetDevices(int serverId)
        {
            return ListDevice(serverId);
        }

        public override Device GetDeviceById(int deviceId)
        {
            OracleContext db = new OracleContext();

            try
            {
                DEVICE loaded = db.DEVICES.Where(d => d.DEVICEID == deviceId).FirstOrDefault();

                if (loaded != null)
                {
                    Device loaDevice = FillDevice(loaded);
                    return loaDevice;
                }
                else
                {
                    return null;
                }
            }
            finally
            {
                db.Dispose();    
            }
        }

        protected override IEnumerable<Device> ListDevice(int code)
        {
            OracleContext db = new OracleContext();

            try
            {
                List<DEVICE> devicelList;
                List<Device> resultList;

                if (code == 0)
                    devicelList = db.DEVICES.Where(d => d.SERVERID == code).ToList();
                else
                    devicelList = db.DEVICES.ToList();

                if (devicelList != null)
                {
                    resultList = new List<Device>();

                    foreach (DEVICE item in devicelList)
                    {
                        Device newDevice = FillDevice(item);
                        resultList.Add(newDevice);
                    }

                    return resultList;
                }
                else
                {
                    return null;
                }
            }
            finally
            {
                db.Dispose();    
            }
        }

        private Device FillDevice(DEVICE item)
        {
            Device current = new Device();

            current.Serverid = item.SERVERID;
            current.Deviceid = item.DEVICEID;
            current.Description = item.DESCRIPTION;
            current.Ipaddress = item.IPADDRESS;
            current.Shots = item.SHOTS;
            current.Matrixnumber = item.MATRIXNUMBER;
            current.Shottime = item.SHOTTIME;
            current.Imageresize = item.IMAGERESIZE;
            current.Imagewidth = item.IMAGEWIDTH;
            current.Imageheight = item.IMAGEHEIGHT;
            current.Devicetype = item.DEVICETYPE;
            current.Devicegroup = item.DEVICEGROUP;
            current.Devicetag = item.DEVICETAG;
            current.Frameinterval = item.FRAMEINTERVAL;
            current.Delaytime = item.DELAYTIME;
            current.Eventinput = item.EVENTINPUT;
            current.Accesspointid = item.ACCESSPOINTID;
            current.Username = item.USERNAME;
            current.Password = item.PASSWORD;
            current.Defaultencoder = item.DEFAULTENCODER;
            current.Isactive = item.ISACTIVE;
            current.Stream = item.STREAM;
            current.Uriaddress = item.URIADDRESS;
            current.Devicesectionid = item.DEVICESECTIONID;
            current.Userid = item.USERID;
            current.Lastupdate = item.LASTUPDATE;
            current.Framerate = item.FRAMERATE;
            current.Initializedevice = item.INITIALIZEDEVICE;
            current.Serviceid = item.SERVICEID;
            current.Insertdelay = item.INSERTDELAY;
            current.Plateposition = item.PLATEPOSITION;
            current.Biosid = item.BIOSID;
            current.Lasttimeactive = item.LASTTIMEACTIVE;
            current.Status = item.STATUS;
            current.Selectedprofiletoken = item.SELECTEDPROFILETOKEN;
            current.Detectionsensibility = item.DETECTIONSENSIBILITY;
            current.OnvifPort = item.ONVIF_PORT;
            current.Nvraddress = item.NVRADDRESS;

            return current;
        }
    }
}

Мой вопрос:

Видите класс Oracle? Если я реализую SQL Server и MySQL, мне нужно будет создать еще 2 класса с одинаковым кодом, потому что существуют разные контексты и разные объекты таблиц (даже объекты, имеющие одинаковые имя и поле в разных контекстах).

Мне действительно не нравится эта практика, и я предполагаю, что это способ создания дженериков или коммьюнити баз для реализации всего этого более чистым способом.

Извините всех за длинный пост. Я старался быть максимально конкретным! Извините за плохой английский тоже:)

Любая помощь будет благодарна!

Спасибо!

0 ответов

Другие вопросы по тегам