-1

I'm working on a template-based C# application.
This application saves entries to a database, using the procedure database.SaveChanged().

I would like to see the list of things which are to be changed, which can be done, using the following method:

IList<T> GetChanged<T>() where T : class;

This means that I could do this as follows:

foreach (var t in database.GetChanged<Alarm>())
{
    log.Debug($"DB Change=[{t}]");
}
foreach (var t in database.GetChanged<Area>())
{
    log.Debug($"DB Change. ClassName=[{t.GetType()}], Change=[{t}]");
}
...

As I have tens of classnames (Alarm and Area are just two out of the fifty-three cases), I would like to do this in an easier way, something like:

List<ClassNames> Class_List= {Alarm, Area, ..., Server.Domain.ClassName, ...}; 
// indeed, namespaces are possible

foreach (var entry in Class_List)
{
    foreach (var t in database.GetChanged<entry>())
    {
        log.Debug($"DB Change. ClassName=[{entry}], Change=[{t}]");

    }
}
Dominique
  • 16,450
  • 15
  • 56
  • 112
  • Is `database` an EF Core DbContext? – Fildor Jun 30 '23 at 12:23
  • No, sorry, it's Telerik OpenAccess related. – Dominique Jun 30 '23 at 12:23
  • 1
    then just get all the types that derive from `DbContext` using something like `myAssembly.GetTypes().Where(x => x.BaseType== typeof(DbContext))`. Even better: just make all your types implement a specific interface. – MakePeaceGreatAgain Jun 30 '23 at 12:25
  • 2
    Looking at the [docs of Telerik](https://docs.telerik.com/data-access/feature-reference/api/context-api/feature-ref-api-context-api-getting-changes) it seems they have a non generic surface that gets you all changes. And besides the thing you use here is the one that has been discontinued in 2016? – Ralf Jun 30 '23 at 12:40
  • Well, you may try using reflection ... iterate properties of `database` which are of type `X` where `X<>` is uknown for me and `Y` is `Alarm`, `Area`, etc (the properties are `Alarms`, `Areas` and so on - i'm not familiar with Telerik OpenAccess so I dont knwo what is `X<>` type in EF is `DbSet<>`) ... then you can obtain type of `Y` and put it to list ... – Selvin Jun 30 '23 at 12:47
  • like this https://dotnetfiddle.net/X7F9SI – Selvin Jun 30 '23 at 12:55
  • 1
    Does this answer your question? [Calling generic method with Type variable](https://stackoverflow.com/questions/3957817/calling-generic-method-with-type-variable) – Selvin Jun 30 '23 at 13:02

1 Answers1

1

It would probably be possible to call the GetChanged<T>() via reflection and fillin the T.

But I think I would create a construction like:

// put all results in a list
var classes = new List<IEnumerable<CommonBaseClass>> { 
    database.GetChanged<Alarm>(),
    database.GetChanged<Area>()
};

foreach (var entry in classes)
{
    foreach (var t in entry)
    {
        log.Debug($"DB Change. ClassName=[{entry}], Change=[{t}]");
    }
}

But, I'm not able to test it here. (things like covariance)

Well, you can waste a lot of time on these kinds of things by fumbling.

Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
  • out of curiosity, so assuming you have a database with 200+ tables, you would still call `database.GetChanged(),` 200 times? for each table once? – Rand Random Jun 30 '23 at 12:37
  • and maintain the code for each new table along the road – Rand Random Jun 30 '23 at 12:39
  • The op talks about things "to be changed" so i would assume its about things tracked in memory locally before handing over to the DB. – Ralf Jun 30 '23 at 12:42
  • 1
    @RandRandom It was just an idea how you can go through "different" collections with a for-loop. But the moment you write your code in such a way, there is something wrong in the design. This falls under code smells of course. For production code anyway, I wouldn't use this. For debug: It is a possibility to check how often updates are. – Jeroen van Langen Jun 30 '23 at 14:25