Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I really don't know what to put in the title, so don't read too much into it.
Anyway, to explain what I'm having trouble with is this. I have three classes: A, B and C. The class hierarchy is as follows:
A <-- B <-- C
(So A is the base class.)
The application in question is a database app. It queries information several tables (A is one table, and B and C are one) and stores it into an instance of C. That part works fine. The problem is when I want to update the table represented by B and C.
To avoid boilerplate code for each code, I use reflection to generate an update query from the class. But if I pass it an instance of a C class, it means it will also pick all the members from A, which is a separate table. Hence the update query will be wrong. And that's where my problem lies. I
want to get all members of B and C without writing a lot of boilerplate code and with a clean, scalable solution. I just don't know how.
(I currently use an approach where I pick all members of the top-level type, then search all of the class's parents and pick all those members and stop collecting members when it finds a specific parent type, e.g. A. This is an awful solution, I think.)
All these classes contains variables fetched from the database and have no methods or fields. Any good ideas on how to approach this problem? I hear C# does not have multiple inheritance, a tool perfect for this job (thanks C#!).
I hope I'm making myself clear.
EDIT1:
To address some questions and give additional context. First off, here's how my system looks today. To query data, I first have a class X, and a query text. The query is run against the database and returns some rows. Then each row is converted into an instance of X and added to a list. The code knows how to convert a row into an X by using reflection and looking at the actual variables in X and the name of the columns in the fetched database row. It then takes column A and places that information into the variable called A in X. So by making a class X and matching that to the database structure is all that's necessary to fetch another table of data.
Sometimes you need to fetch data from multiple tables and put them together. To do this, I need a class X that matches the information fetched from the query. There are a lot of data that I fetch and all this data has a common subset fetched from table A. The rest is fetched from a lot of other tables that contain additional data. Hence the type system always looks like something A <-- B, where A is the common subset of all data I fetch. This works great for queries. I can add additional data and a class and I'm done. No more boiler plate code.
But that's only half the story. I need to update these tables too (I don't need to update A). But to do that, I need to separate the data fetched from the table A, the common subset. Here's how I do the updating:
Connection.RunUpdateQuery(..., Utility.ToDictionary(Entry));
Where Entry is the class containing the information to update into the target table. So I convert the class into a Dictionary representing column name, column value and send that the RunUpdateQuery which generates an update sql statement and sends it to the database. Again, this is really nice because I have to write absolutely no boilerplate code.
But Utility.ToDicionary can't know what subset of information I actually want to insert. What it does is just take every variable in the class and transform it into a dictionary where the name of the variable is the column name (i.e. the key of the dictionary). In this case, if I pass it a C, I really only just want B and C because they're part of the target table I want to update. The A subset is part of another table which I don't want to update.
If there's a framework that does all this work, I'm all for it. But right now, I don't have the time to rewrite this code. So I'm going to have to wait with that that until later.
This is also my own database that I am designing. I'm in charge of everything regarding the project's design.
I really don't want to generate queries, even if it just means running a tool because a) it means more work every time the database changes and b) it means more bugs because I might forget to update certain places when something changes. With my current reflection-based solution, I don't have to change anything. I just have to design the database and an appropriate class (which I have to anyway since I need to translate the rows from the db into appropriate first-class citizens in the code so I can work with them more easily).
Using attributes doesn't seem like a good way of doing it either because it's all context-dependent. The caller that wants to update a table must be able to choose which fields should be updated in the database, but not at such a fine-grained level. The caller should simply be able to select the class to update, so to speak.
Maybe this gives some clarity into my problem.
EDIT2:
Examples of class A, B, C:
C:
public class PumpEntry: SignalEntryD
{
public uint? Addr;
public uint MasterlistIdx;
public bool MinDominant;
public uint? TriggerInterval;
public uint? SpDef;
public uint? MinDef;
public uint? MaxDef;
public uint? Step0Def;
public uint? Step1Def;
public uint? Step2Def;
public uint? Step3Def;
public uint? Step4Def;
public uint? Step5Def;
public uint? ExReqFacBACNet, ExSpFacBACNet;
public decimal? DeltaTX0Def, DeltaTX1Def, DeltaTX2Def, DeltaTX3Def;
public uint? DeltaTYMinDef, DeltaTY0Def, DeltaTY1Def;
public string DeltaTSensor1, DeltaTSensor2;
public int? ReqLimitMethodDef;
}
B:
public class SignalEntryD: DeviceEntry
{
public int? Channel;
public int? pCOeNum;
}
A:
public class DeviceEntry: DbType
{
public int Id;
public DeviceType Type;
public string Name;
public string CMCategory;
public bool Generate;
public new string ToString() { return Name; }
}
You should probably use an ORM library such as Entity Framework or NHibernate. They know how to deal with inheritance (they offer several strategies you can choose from). Then you don't need to write any boilerplate code at all.
I guess the typical C# solution for this is to mark your fields with custom attributes, and use that in reflection to decide whether or not it should be included.
public class DoSerializeAttribute : Attribute {}
public class C : B {
[DoSerialize]
public MyMember { get; set; }
}
And later in your reflexion code you can use GetCustomAttribute method.
You say you are using reflection. In thise case, doing this:
C myObject = new C();
myObject.GetType().GetProperties(System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.DeclaredOnly)
Should only give you the properties declared specifically in C, not in B or A. From there on you could use myObject.GetType().BaseType which would give you B, and its BaseType would be A.
Check it in this fiddle
I made a rough query generator here: check it in this other fiddle, which generates all update queries needed (if you pass a C, it'll generate queries for tables A, B and C), except for the types you pass as parameters.
With this information, you could easily generate your update queries dynamically and for any levels of hierarchy.
I'd give you more specific code but you wrote none
Not saying this is the perfect solution, but it's what you are asking for in your question
Without learning ORM (which is a proper thing, but may be overkill in a simple case and by saying overkill I mean learning curve) you can use LINQ-to-SQL as model to access your data instead of creating C class yourself. Create dbml file (see e.g. here regarding what is it). As result you get you table class code-generated, then you just use it
using (var context = new SomeContext()) // static connection string
{
var query = context.SomeTable.AsQueryable();
if (SelectedFilter == Today)
query = query.Where(o => o.Id >= DateTime.Today);
...
// constructing ViewModel items (WPF, MVVM)
foreach (var item in query)
items.Add(new Item()
{
Id = item.Id,
...
}
}
Item (B in your example) is a simple class to hold values. You can populate other properties of Item using another query or context (another table or database).
When you want to update database you simply do
using (var context = new SomeContext())
{
var change = context.SomeTable.First(o => o.Id == item.Id);
change.Comment = item.Comment;
...
context.SubmitChanges();
}
Basically you write those methods once for your ready-made ViewModel item (can be a complicated query to many tables or multiple queries to different databases). Updating part can be methods of Item or, better, of ViewModel (because it can be optimized, e.q. when only changing Comment you don't need to update other fields and perform other queries).
Boilerplate? Not really, look into SomeContext generated cs-file to see some.
To be frank, I personally think your current solution is a mess. There are infinte amount tools available for this kind of stuff, why reinvent (and very badly to be honest) the wheel?
Anyhow, trying to solve your issue in your particular setup, here is what I'd do:
First off, get rid of inheritance. You shouldn't be using it at all. Inheritante is most definitely not a tool meant to be used as a means to avoid data duplication, the simple notion is horrendous.
You have 2 distinct tables in your DB, code them as such.
DbType
PumpEntry
I have no idea why you need the intermediate SignalEntryD. If its not a table in your DB then it shouldn't appear anywhere in your code (I'm guessing its also due to code duplication).
Be consistent: if fields Channel and pCoeNum are duplicated throughout different tables in your database then just duplicate them in your entities. Otherwise, create a table in your DB and then model it in your entities (as you do with DbType). Don't mix things up, do it the same way on both ends.
For reasons that become clear later on, make both your entities implement a "dummy" interface ITable (type safety) and a default parameterless constructor (including all your properties / fields of course).
Now the problem is, if I understand correctly, that you are receiving a Dictionary<string, object> with user updated values and you need to update a given table, the problem being that the dicitonary can contain fields that belong to different tables (I won't get into how you ended up with this problem to begin with, I'll just ride along...).
Well then, simply create a way to build any entity from a random dicitionary using reflection (my code uses properties, but it is equivalent with fields):
public static T CreateTable<T>(IDictionary<string, object> values) where T: ITable, new()
{
var table = new T();
foreach (var propInfo in typeof(T).GetProperties())
{
if (values.ContainsKey(propInfo.Name))
{
propInfo.SetValue(table, values[propInfo.Name]);
}
}
return table; //note that any property not defined in the dictionary will be initialized to the field's type default value.
}
And now, you'd use it as follows:
Connection.RunUpdateQuery(..., CreateTable<TableC>(Utility.ToDictionary(Entry))); //only fields of TableC will be passed along.
I'm hoping this is straight forward. I'm trying to implement the Command Pattern in my MVC application I'm making. The only issue I'm seeing is that the number of Command objects is really high.
I have 11 tables each with around 20 fields that need to be updated.
My question is do I need to have a different object for each field?
This is a healthcare application, so let me give an example.
I have a table called KeyHospital, this table stores Hospital information and only Hospital information for our Hospital Clients. I've used Linq to SQL for my connection to the database. The KeyHospital table is probably the largest as far as fields go. What I've done is create a new object per field.
public class ChangeHospitalDEA : ICommand
{
public ChangeHospitalDEA(int id, string newDEA)
{
var Thishospital = (from Hospital in _context.Keyhospitals
where Hospital.ID == id
select Hospital).Single();
Thishospital.DEAnum = newDEA;
}
}
I have ICommand as an abstract class.
public abstract class ICommand
{
public AllkeysDataContext _context = new AllkeysDataContext();
public void Execute()
{
_context.SubmitChanges();
}
}
Am I doing this correct? I just feel like I'm writing lots of code for this and it's one of my first times using the Command Pattern.
Considerably too granular. Instead, you should define commands for actions such as inserting a new entity, (graph of one or more related objects) updating an entity, etc.
A command would be used whenever you want to perform an action. In some cases changing a single field may constitute an action, such as returning additional data, or providing suggestions. Such as an AJAX call to validate an entered address. Also, ICommand is a poor name choice for a base abstract class. ICommand is a common interface for command architectures. (the "I" prefix is conventionally reserved for interface names.) I deal predominantly with MVVM but I would suspect that MVC has a common command interface already.
This is might not be what you want to hear but I would restructure your user interface to be Tasks based UI and construct your UI into common Tasks for example Change Drug Enforcement Administration number and these tasks can be refined over time.
If you have existing analytics you will notice that certain field will be only changed together and these could be logically grouped into common tasks
I also feel that is it is a bad practice to hide database calls within constructors and would move that linq statement to the Execute method and have the ctor only initialise public properties or private fields and have them field being used within the execute method.
Major reason for moving the query into the execute method is to reduce the time the chances of any Optimistic concurrency errors.
Also I also feel that calling the Base class ICommand is not a good practice and may lead to confusion in the future and would recommend you calling it CommandBase or changing it to an interface once again.
This is more of a technical "how-to" or "best approach" question.
We have a current requirement to retrieve records from the database, place them into an 'in-memory' list and then perform a series of calculations on the data, i.e. maximum values, averages and some more specific custom statistics as well.
Getting the data into an 'in-memory' list is not a problem as we use NHibernate as our ORM and it does an excellent job of retrieving data from the database. The advice I am seeking is how should we best perform calculations on the resulting list of data.
Ideally I would like to create a method for each statistic, MaximumValue(), AverageValueUnder100(), MoreComplicatedStatistic() etc etc. Of course passing the required variables to each method and having it return the result. This approach would also make unit testing a breeze and provide us with excellent coverage.
Would there be a performance hit if we perform a LINQ query for each calculation or should be consolidate as many calls to each statistic method in as few LINQ queries as possible. For example it doesn't make much sense to pass the list of data to a method called AverageValueBelow100 and then pass the entire list of data to another method AverageValueBelow50 when they could effectively be performed with one LINQ query.
How can we achieve a high level of granularity and separation without sacrificing performance?
Any advice ... is the question clear enough?
Depending on the complexity of the calculation, it may be best to do it in the database. If it is signifcantly complex that you need to bring it in as objects and encur that overhead, you may want to avoid multiple iterations over your result set. you may want to consider using Aggregate. See http://geekswithblogs.net/malisancube/archive/2009/12/09/demystifying-linq-aggregates.aspx for a discussion if it. You would be able to unit test each aggregate separately, but then (potentially) project multiple aggregates within a single iteration.
I dont agree that it is best "to do it all in the database".
Well written Linq Queries will result in good SQL queries being executed against the database, which should be good enough performance wise (if you are not going to do dwh stuff). This is assuming you are using the Linq Provider for NHibernate and not Linq to Objects.
It does look good, you can change it easily and keeps your business logic in one place.
If that is too slow for your needs, you might check the SQL code created and tweak your linq queries, are try to precompile them, and in the end you can still go back to writing the beloved stored procedures - and start to spread your business logic all over the place.
Will there be a performance hit? Yeah, you might lose a few millisecs, but is that worth the price you have to pay for separating your logic?
To answer the "I would like to create a method for each statistic" concern, I would suggest you to build a kind of statistician class. Here is some pseudo code to express the idea :
class Statistician
{
public bool MustCalculateFIRSTSTATISTIC { get; set; } // Please rename me!
public bool MustCalculateSECONDSTATISTIC { get; set; } // Please rename me!
public void ProcessObject(object Object) // Replace object and Rename
{
if (MustCalculateFIRSTSTATISTIC)
CalculateFIRSTSTATISTIC(Object);
if (MustCalculateFIRSTSTATISTIC)
CalculateSECONDSTATISTIC(Object);
}
public object GetFIRSTSTATISTIC() // Replace object, Rename
{ /* ... */ }
public object GetSECONDSTATISTIC() // Replace object, Rename
{ /* ... */ }
private void CalculateFIRSTSTATISTIC(object Object) // Replace object
{ /* ... */ }
private void CalculateSECONDSTATISTIC(object Object) // Replace object
{ /* ... */ }
}
Would I have to do this, I would probably try to make it generic and use collections of delegates instead of methods, but since I don't know your context, I'll leave it to that. Also note that I only used Object members of object class, but that's only because I'm not suggesting you to use DataRows, Entities, or what not; I'll leave that to the other folks that know more then me on the subject!
One of my fellow developer has a code similar to the following snippet
class Data
{
public string Prop1
{
get
{
// return the value stored in the database via a query
}
set
{
// Save the data to local variable
}
}
public void SaveData()
{
// Write all the properties to a file
}
}
class Program
{
public void SaveData()
{
Data d = new Data();
// Fetch the information from database and fill the local variable
d.Prop1 = d.Prop1;
d.SaveData();
}
}
Here the Data class properties fetch the information from DB dynamically. When there is a need to save the Data to a file the developer creates an instance and fills the property using self assignment. Then finally calls a save. I tried arguing that the usage of property is not correct. But he is not convinced.
This are his points
There are nearly 20 such properties.
Fetching all the information is not required except for saving.
Instead of self assignment writing an utility method to fetch all will have same duplicate code in the properties.
Is this usage correct?
I don't think that another developer who will work with the same code will be happy to see :
d.Prop1 = d.Prop1;
Personally I would never do that.
Also it is not the best idea to use property to load data from DB.
I would have method which will load data from DB to local variable and then you can get that data using property. Also get/set logically must work with the same data. It is strange to use get for getting data from DB but to use set to work with local variable.
Properties should really be as lightweight as possible.
When other developers are using properties, they expect them to be intrinsic parts of the object (that is, already loaded and in memory).
The real issue here is that of symmetry - the property get and set should mirror each other, and they don't. This is against what most developers would normally expect.
Having the property load up from database is not recommended - normally one would populate the class via a specific method.
This is pretty terrible, imo.
Properties are supposed to be quick / easy to access; if there's really heavy stuff going on behind a property it should probably be a method instead.
Having two utterly different things going on behind the same property's getter and setter is very confusing. d.Prop1 = d.Prop1 looks like a meaningless self-assignment, not a "Load data from DB" call.
Even if you do have to load twenty different things from a database, doing it this way forces it to be twenty different DB trips; are you sure multiple properties can't be fetched in a single call? That would likely be much better, performance-wise.
"Correct" is often in the eye of the beholder. It also depends how far or how brilliant you want your design to be. I'd never go for the design you describe, it'll become a maintenance nightmare to have the CRUD actions on the POCOs.
Your main issue is the absense of separations of concerns. I.e., The data-object is also responsible for storing and retrieving (actions that need to be defined only once in the whole system). As a result, you end up with duplicated, bloated and unmaintainable code that may quickly become real slow (try a LINQ query with a join on the gettor).
A common scenario with databases is to use small entity classes that only contain the properties, nothing more. A DAO layer takes care of retrieving and filling these POCOs with data from the database and defined the CRUD actions only ones (through some generics). I'd suggest NHibernate for the ORM mapping. The basic principle explained here works with other ORM mappers too and is explained here.
The reasons, esp. nr 1, should be a main candidate for refactoring this into something more maintainable. Duplicated code and logic, when encountered, should be reconsidered strongly. If the gettor above is really getting the database data (I hope I misunderstand that), get rid of it as quickly as you can.
Overly simplified example of separations of concerns:
class Data
{
public string Prop1 {get; set;}
public string Prop2 {get; set;}
}
class Dao<T>
{
SaveEntity<T>(T data)
{
// use reflection for saving your properies (this is what any ORM does for you)
}
IList<T> GetAll<T>()
{
// use reflection to retrieve all data of this type (again, ORM does this for you)
}
}
// usage:
Dao<Data> myDao = new Dao<Data>();
List<Data> allData = myDao.GetAll();
// modify, query etc using Dao, lazy evaluation and caching is done by the ORM for performance
// but more importantly, this design keeps your code clean, readable and maintainable.
EDIT:
One question you should ask your co-worker: what happens if you have many Data (rows in database), or when a property is a result of a joined query (foreign key table). Have a look at Fluent NHibernate if you want a smooth transition from one situation (unmaintainable) to another (maintainable) that's easy enough to understand by anybody.
If I were you I would write a serialize / deserialize function, then provide properties as lightweight wrappers around the in-memory results.
Take a look at the ISerialization interface: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializable.aspx
This would be very hard to work with,
If you set the Prop1, and then get Prop1, you could end up with different results
eg:
//set Prop1 to "abc"
d.Prop1 = "abc";
//if the data source holds "xyz" for Prop1
string myString = d.Prop1;
//myString will equal "xyz"
reading the code without the comment you would expect mystring to equal "abc" not "xyz", this could be confusing.
This would make working with the properties very difficult and require a save every time you change a property for it to work.
As well as agreeing with what everyone else has said on this example, what happens if there are other fields in the Data class? i.e. Prop2, Prop3 etc, do they all go back to the database, each time they are accessed in order to "return the value stored in the database via a query". 10 properties would equal 10 database hits. Setting 10 properties, 10 writes to the database. That's not going to scale.
In my opinion, that's an awful design. Using a property getter to do some "magic" stuff makes the system awkward to maintain. If I would join your team, how should I know that magic behind those properties?
Create a separate method that is called as it behaves.
I have a Database class which contanins the follwing methods:
public bool ExecuteUDIQuery(string query) // UDI = Update Delete Insert
public bool ExecuteSelectQuery(string query)
public bool ExecuteSP(string sp, string[,] parms)
public int ExecuteSPReturnValue(string sp, string[,] parms)
The results of the methods are stored in private datasets or datatables. These objects are defined as getters.
There're about 10 classes which use the Database class. Every class creates an object of the class Database. Now i was thinking to make the Database class static. Is this a good idea? If so, why? Of not, why not?
If I understand, the database class has some properties that store the result of the query? If so, you cannot make them static, since that is not thread-safe. If the result of a query is stored in these properties, what would happen if a second query would execute right after the first? It would be stored in the same static variable. The same goes for a web application: the result of another user browsing the site would change the results of the first user.
EDIT: To summarize, do NOT make the class static when you store the result of the queries in static variables, especially not when the class is used in a website, as the properties value will be shared amongst all visitors of your website. If 20 visitors do a query at the same time, visitor 1 will see the results of visitor 20's query.
In your specific example, I'd advise against making the class static: you're keeping state in the Database class, and by making the class static, that state will be shared amongst all classes using your Database. In your current setup, each Database instance keeps its own state, so there's no problem with Database calls interfering with each other.
If you'd refactor the Database class to return the datasets when doing a method call, you'd be fine making it static: there would be no stateful information left in the Database class.
But since this is not the case: no, don't make the class static.
In addition to the others comments about thread safety there is also the issue of paralellization. In your case you won't be able to open several connections to the database at the same time and you won't be able to perform multiple paralell queries, even if thread safety of the results isn't an issue.
So I agree with the others, don't make a static class out of it.
Making the class static may be convenient, but creating new instances of it probably won't be an expensive operation so there probably isn't much to gain performance-wise either.
Edit:
I saw in a comment that you want to use your class on a web site. In that case you REALLY shouldn't do this. With a static database class you will only be able to safely serve one request at any time, and that is not what you want.
It depends on what kind of database or ORM that you're using. But in my experience it's seemed like a good idea but ended up shafting me. Here's how it did for me in LINQ-to-SQL:
I had a repository class that had a static variable to a data context. It worked at first, but when I had to make many more repository classes I ended up getting bugs as I hacked along. It turns out that data context in LINQ-to-SQL caches up all results and there is no way to refresh them. So if you added a post in a table in one context, it won't show up in other that cached that table. The solution was to remove the static modifier and let the repository create the context in the constructor. Since the repository classes were constructed as they were used, so would a fresh new data context.
You could argue that static variables leaves less footprint in memory, but the footprint for a data context is quite small to begin with and will be garbage collected in the end.
Contrary to the answer post.
I've built a webframework with a static database access it works great and gives great performance.
You can check out the source code at http://www.codeplex.com/Cubes
If you are just executing queries against the DB, then yes make it static. You only have to create an instance if this object needs to keep some sort of state.
If you have a static method you need to keep track of instances when you open and close the database.
So what you probably want to do is have a static Method called instance or current instance. And within you create a new instance of your db-class returning it in the static method.
Your methods good for static usage. I think, you have no trouble to convert them to static methods for now.
but later maybe you will need to manage transaction. leaving the transaction management to a class is saves lots of time I think. and this scenario is best fits with a nonstatic class.