I would like to make a generic method to import data into my application.
For example, say I have:
private static async Task<int> ImportAccount(string filename)
{
var totalRecords = await GetLineCount(filename);
var ctx = new AccountContext();
var count = 0;
var records = 0;
using (var stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
var data = line.Split('\t');
var acc = new Account(data);
await ctx.Accounts.AddAsync(acc);
// need this to avoid using all the memory
// maybe there is a smarter or beter way to do it
// with 10k it uses about 500mb memory,
// files have million rows+
if (count % 10000 == 1)
{
records += result = await ctx.SaveChangesAsync();
if (result > 0)
{
ctx.Dispose();
ctx = new AccountContext();
}
}
count++;
}
}
}
await ctx.SaveChangesAsync();
ctx.Dispose();
return records;
}
In the above example I am importing data from a tab delimited file into the Accounts db.
Then I have properties, lands, and a whole lot of other db's I need to import.
Instead of having to make a method for each db like the above, I would like to make something like:
internal static readonly Dictionary<string, ??> FilesToImport = new Dictionary<string, ??>
{
{ "fullpath to file", ?? would be what I need to pass to T }
... more files ...
};
private static async Task<int> Import<T>(string filename)
Where T would be the DB in question.
All my classes have 1 thing in common, they all have a constructor that takes a string[] data
.
But I have no idea how I could make a method that I would be able to accept:
private static async Task<int> Import<T>(string filename)
And then be able to do a:
var item = new T(data);
await ctx.Set<T>().AddAsync(item);
And if I recall correctly, I would not be able to instantiate T with a parameter.
How could I make this generic Import method and is it possible to achieve?