Approach mapping objects to database entities - c#

I have to create an import from excelfiles to a database.
I've created a little system which mapps my excelfile to some kind of "excel entities". Some of these entites contain information for more than one database table and for other entites I need to calculate the id in the database etc. I am using the entityframework to map the database to objects.
Now my problem is, that I need a clean approach to map between my excelfile structure and my database structure.
Is there any pattern to solve this problem in a clean way? I don't want to check every attribute whether it has changed,... I just need to synchronize the database with my excelfile. But the excefile does not exactly look like my database schema.
Would be very nice if someone would know a pattern or an approach how to solve the problem.

Looks to me like you actually have two problems to solve: 1) Get the information out of the excel files into a nice schema; and 2)synchronize the database. Looks like you have #2 well under control if you're considering entity framework. To solve your #1 issue, you more than likely have to create a parser that can fill in the entities that are created in your #2 solution.
TL;DR: Separate the file parsing from the synchronizing. Get all your objects first, then update the database.
Edit:
You'll have to create a mapper next. Something that can link two objects by property names. Look at "Reflection", "Extension methods" and a more generic search for mappers. I would create something that would work like this:
object1.Map("Property1",object2,"Property2");
object1 would be your database entity, Property1 the name of the property you want to map to, object2 would be the excel entity and Property2 the name of the property to map from.
PS: If the extension method is done correctly, you can 'chain' the mapping: object1.Map("Property1", object2, "Property2").Map("Property3", object3, "Property4")
and so on. You can even select different objects to map to.

Related

Flattening multiple tables to a single type

I'm trying to model a database currently using EntityFramework's Fluent Configuration. I cannot edit or otherwise control the database schema. The entity I am trying to model has a lot of look-up tables - for example, one property (it's name) has a whole table devoted to it with a name associated with an id (which is it's language). In other words, it looks a bit like this in the database:
Entity
string[] Names
Entity_Names
string Name
int LanguageId // 9 = English
However, I am trying to condense this into
Entity
string Name // I only want the English name
Using a SQL query, this would be pretty simple - but how can I do this via Entity Framework's fluent configurations? There are a lot more of these instances as well, but this is the simplest example I could come up with.
If you do manage to flatten the model this way, it's almost certainly going to be a read-only view of the data. There's no way for Entity Framework to know that a string property should be looked up in another table and replaced with an integer id.
So that leaves two options if you're okay with it being view-only. Write a database view that replaces the ids with the strings and build an entity for that view.
Or build entities that are compatible with the schema model and project the data into a dto.
The second approach is the one I'd prefer as it means you'd still have a compatible entity model if you do need to CRUD.

Making generic getters and setters

I have a problem where I have to get the column names and their values from all the Tables in my schema and show that the result in a grid.
I have used the direct approach for this but I have to implement the SqlSiphon structure. For this I have to make getters and setters of each of the column of each Table in the schema which is impossible.
What should I use to get the Column names and their values dynamically from the table.
SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = '" + #Tablename1 + "' AND TABLE_SCHEMA='dbo'"
What will be the best dynamic solution?
And what will be Best to use List , Dictionay or something like 2d Array which will give the column names as well as column values?
A few suggestions:
I'm not completely clear on what you're trying to achieve, but consider using an ORM (Linq2SQL, WEF, NHibernate)
In .NET, a suitable type to represent a database table would be a DataTable
Edit: After a few more re-reads I think I understand what you're asking - you already have a database/schema and you want to automatically create the entity classes needed by SqlSiphon. This is called "database-first" (as opposed to model-first). However, from a brief scan of the SqlSiphon documentation it appears it does not support database-first. Is this why you are trying to put the columns into a grid - to make it easier to manually create the entity classes for SqlSiphon?
Edit2: Note that trying to use an ORM on top of a database whose schema is frequently modified will be problematic. My next guess is that you're trying to figure out how to create an entity class in SqlSiphon which you can use to retrieve database schema information like table columns? I'm still struggling to understand what you're actually asking here - perhaps you can update your question?
Edit3: I think the answer to your question is take a different approach to your design - ORM's like SqlSiphon are not intended to be used to retrieve and modify the database schema itself.
Might be worth taking a step back an comparing against how other people solve similar problems.
Typically, each table on a database represents an entity, and you also have a class per entity, and you may use an ORM system to avoid duplication of work. So, in a typical system, you have a table for customers, and a table for invoices, and a table for invoice lines, etc. and then a class that represents a customer, a class for an invoice, a class for an invoice line, etc. As you later add functionality (and possible columns/properties) you change the classes, rather than just seeing what columns are on the database - you can of course decorate these with XML documentation and get Intelisense goodness.
There are many ORM systems out there, and each have their strengths and weaknesses, but I personally like LINQ to SQL for adding onto an existing data model.

Store behavior class with nHibernate

I would like to know if there is a way how to store classes only with behavior to database with nHibernate.
What I mean. I have a solution where I have used decorator pattern, something like on class diagram
Here is the problem what Iam trying to solve. I have a class ClassWithStoredBehaviorInProperty and has a property DesiredBehavior of type IBehavior. Somewhere else I mix up behavior f.e. var beh = new FlyBehavior(new WalkBehavior(new BatmanBehavior)) and store it in DesiredBehavior property. And here is my question. Is there any way how to store this in database with nHibernate and then Load it correctly or I have to do some workaround. If it is possible, how to map it? Thanks
You can have hierarchical data structures handled by NHibernate. From a database perspective, The Decorator Pattern is simply a hierarchical structure where there is only one child node rather than a collection. There is some introductory information here.
So you can quite easily map subclasses of the same hierarchy using the 'table per class hierarchy' approach, where each Decorator becomes a row in the table and points to an Inner Decorator. In your table you use a discriminator column so when retrieving from the database, NHibernate knows what type of class it needs to instantiate. Obviously the 'code' that realises the particular behavior associated with each Decorator would not live in the database.

Add an extra column to my model in an .edmx file

I want to add an extra column, similar to a join to my model based on the ID. Is this possible?
For example:
ProductsModel
ID
DeliveryID
DeliveryModel
DeliveryID
DeliveryDescription
What I'd like to do is add the DeliveryDescription column to my ProductsModel in my .edmx file. I know its possible to add 3 property types (scalar, navigation, complex) are one of these the solution?
No. Default entities must exactly match your tables. There are situations where this is not the true but all involve advanced mapping features like splitting or inheritance. By looking at your tables neither of this is case.
What you are trying to do is equivalent to database view. It is possible in EF by either using QueryView or DefiningQuery. Both will result in new read-only entity type. To use these advanced features you must manually edit EDMX file (and in case of DefiningQuery you cannot use update from database any more because it would delete your changes).
You most probably need this for some data presentation so instead of modifying your mapped entities create a new class outside of EF just for presentation and fill it from entities.

NHibernate and Modular Code

We're developing an application using Nhibernate as the data access layer.
One of the things I'm struggling with is finding a way to map 2 objects to the same table.
We have an object which is suited to data entry, and another which is used in more of a batch process.
The table contains all the columns for the data entry and some additional info for the batch processes.
When it's in a batch process I don't want to load all the data just a subset, but I want to be able to update the values in the table.
Does nhibernate support multiple objects pointed at the same table? and what is the thing that allows this?
I tried it a while ago and I remember that if you do a query for one of the objects it loads double the amount but i'm not so sure I didn't miss something.
e.g.
10 data entry objects
+
10 batch objects
So 20 object instead of 10.
Can anyone shed any light on this?
I should clarify that these objects are 2 different objects which in my mind should not be polymorphic in behaviour. However they do point at the same database record, it's more that the record has a dual purpose within the application and for sake of logical partitioning they should be kept separate. (A change to one domain object should not blow up numerous screens in other modules etc).
Thanks
Pete
An easy way to map multiple objects to the same table is by using a discriminator column. Add an extra column to the table and have it contain a value declaring it as type "Data Entry" or "Batch Process".
You'd create two objects - one for Data Entry and Batch Process. I'm not entirely sure how you enact that in regular NHibernate XML mapping - I use Castle ActiveRecord for annotating, so you'd mark up your objects like so:
[ActiveRecord("[Big Honking Table]",
DiscriminatorColumn = "Type",
DiscriminatorType = "String",
DiscriminatorValue = "Data Entry")]
public class Data Entry : ActiveRecordBase
{
//Your stuff here!
}
[ActiveRecord("[Big Honking Table]",
DiscriminatorColumn = "Type",
DiscriminatorType = "String",
DiscriminatorValue = "Batch Process")]
public class Batch Process : ActiveRecordBase
{
//Also your stuff!
}
Here's the way to do it with NHibernate + Castle ActiveRecord: http://www.castleproject.org/activerecord/documentation/trunk/usersguide/typehierarchy.html
Note that they use a parent object - I don't think that's necessary but I haven't implemented a discriminator column exactly the way you're describing, so it might be.
And here's the mapping in XML: https://www.hibernate.org/hib_docs/nhibernate/html/inheritance.html
You can also, through the mapping, let NHibernate know which columns to load / update - if you end up just making one big object.
I suppose you just might be overengineering it just a little bit:
If you worry about performance, that's premature optimization (besides, retrieving less columns is not much faster, as for saving you can enable dynamic updates to only update columns that changed).
If you trying to protect the programmer from himself by locking down his choices, you complicating your design for not so noble a cause.
In short, based on my 10 yrs+ of experience and my somewhat limited understanding of your problem I recommend you think again about doing what you wanna do.

Categories

Resources