I am a beginner in C# programimg and I am looking for a way to make some generics to better work with Entity Framework using multiple databases.
My application was built using only Oracle Database, using all the entities inside my application. Now we have the need to implement SQl Server and MySQL in this application too.
For this I did the following steps:
- Removed all entities from my main application;
- Created 3 class libraries, one for each database containing only the models and EF generated classes;
- Created a 4th class library that contains generic classes to be filled by the objects of each database.
This "generic" class library contain this items for each table:
- A class with the same name of the table and the same fields (all databases have the same table and field names);
- An interface that implements base methods;
- An abstract class that implements the interface methods;
- A class that inherits from my abstract class for each database;
- A factory class that creates the required database class using a database type enum.
Below I post a example using my devices table:
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;
}
}
}
My question is:
See the Oracle class? If I implement SQL Server and MySQL I will have to create 2 more classes with the same code because there are different contexts and differnt table objects (even the objects having the same name and field in different contexts.
I am really not liking this pratice and guess if is that a way to create generics or commom bases to implement all this in a cleaner way.
Sorry evebody for the long post. I tried to be as specific as possible! Sorry for the bad english too :)
Any help will be thankful!
Thanks!