5

The title is not so accurate, but I couldn't come up with a better one.

I’m trying to write a MySQL Connector for MS‘ Forefront Identity Manager (FIM is basically a sync engine that synchronizes identities between various data sources using a meta directory). But I’m having difficulties to come up with an appropriate design.

Let’s say I want to import user data from a db into FIM’s metaverse. A user object has various attributes like firstname, lastname, address etc. In the database these attributes can be distributed between multiple tables. FIM ultimately needs these attributes to be merged into one object. So the user needs to configure the connector to tell it how the data is stored in the DB.

I was wondering what would be the “best” way to represent this configuration. Two alternatives come to (my) mind:

  1. I could just save a select query that merges/joins the data, so that the result is a single “table” with all the desired attributes. The problem with this is that I think I would have to do some kind of parsing on this query-string to create a fim-compatible-schema out of it (which is basically the name of the object type (f.e. “person”) and a list of attributes). This schema needs to be creatable from the query-string alone without actually executing the query (I could execute some fake queries if that would simplify the process).
  2. I could create some classes to represent the database schema, i.e. the tables and relationships. Since I’m not that experienced with MySQL (or databases at all for that matter) I’m running the risk of missing some special cases. Also it might be some kind of overkill, since the schema can be assumed as fixed once it's configured.

Does anyone have same advice on which alternative to choose and how to tackle the problems that would come with it? Or is there another – better – alternative I didn’t think of? Any advice would be greatly appreciated! If something is not clear, please let me know.

Edit: Since there have been some questions on the use case, I'm going to elaborate a bit:

As I've said, I'm developing a Management Agent for FIM. FIM provides a so called Extensible Connectivity Management Agent, which is basically one single class implementing a few interfaces. (See this technet guide for a sample implementation).

Since I want to develop a generic agent for managing identities in a MySQL database, I don't know the database layout at compile time. When the enduser wants to use the management agent, he needs to decide, which attributes of the identities he'd like to manage. So I need to give the user some way to configure the management agent. My main question is, how to design the classes to save this configuration.

Lets look at a simple example:

Say you want to manage employee identities. To keep it simple, we have three attributes:

  • firstName
  • lastName
  • department

In this example case it could be f.e. just one single table with 4 columns (the attributes plus an id). But it could also be the much better design, which uses two tables, one user table and one department table, using a 1:1 relation to define the users department.

FIM requires me to consolidate these attributes in one object. It provides a class CSEntryChange which has an AttributeChanges collection member. I would then create some instances of AttributeChange (which basically contains the attribute name und it's value) and add them to the collection. So the user-editable configuration must tell the management agent how it can get the users with all defined attributes from the db and how to create and modify users in that database.

So ideally I'd have an intance of some "MySQLSchema" class (which is configured by the user up front), that could return a List<CSEntryChange> (I wouldn't actually use the CSEntryChange class for the sake of decoupling, but you should get the point) that contains all users in the db (pagination might be a requirement but I can figure that out later). In addition I'd like to able to pass it a CSEntryChange which would result in the corresponding database entries beeing updated (or created if not yet present).

I hope this clear it up a bit more :)

Tobi
  • 5,499
  • 3
  • 31
  • 47
  • U may take a look at this post http://stackoverflow.com/questions/17435224/mapping-c-sharp-objects-to-database-schema, mayb this helps clarify. I would always try a ORM approach regardless the used database software. – YvesR Jan 17 '14 at 08:52

5 Answers5

2

I think that your real question is, "How to access MySQL entities over C#?"

To begin with, I hope you are building this in as a MVC application.

I would suggest sticking to a full Microsoft stack for purposes of learning and ease of implementation.

With this in mind, you will want to create an EntityFramework MySQL data provider in the following steps:

  1. Create a new project and and EntityFramework either through the Nuget package manager UI or package manager console by typing Install-Package EntityFramework -Version 6.0.2 (and add a reference to this project from your web project). Look half way down the page for "Configure EntityFramework to work with a MySQL database".

  2. Install the MySQL provider for entity framework through the Nuget package manager UI or by typing Install-Package MySql.Data.Entity in the package manager console

The next step requires understanding of db configuration changes, that are nicely detailed here - Configure EntityFramework to work with a MySQL database.

You should end up with a nice class structure which will allow you to traverse your entities' navigation properties through EF.

Depending on the level of security your application requires, you may also want to create data transfer objects (DTOs) that contains only the data required for your remote calls - keeping your data calls efficient.

This is by no means a definitive guide on how to do this, but hopefully gives you a start in the right direction.

With regards to your step #1 above:

I could just save a select query that merges/joins the data, so that the result is a single “table” with all the desired attributes. The problem with this is that I think I would have to do some kind of parsing on this query-string to create a fim-compatible-schema out of it (which is basically the name of the object type (f.e. “person”) and a list of attributes). This schema needs to be creatable from the query-string alone without actually executing the query (I could execute some fake queries if that would simplify the process).

I am slightly confused by this. Are you saying that you want to dynamically update your database schema based application requests?

ElHaix
  • 12,846
  • 27
  • 115
  • 203
  • sorry for taking so long to respond, had no time. would your approach support configuring the db-schema by say an XML-file? because the whole point of my problem is, that the enduser needs to setup my service with the db-schema of HIS/HER database. – Tobi Jan 24 '14 at 08:57
  • Can you talk about your use-case a little more - specifically what the reason is for having the end user defining the db schema? Off the top it doesn't sound like good design, but you may have a perfectly valid reason for this that makes sense. If that is the case, I would recommend a NoSQL database, some of which are listed here: http://nosql-database.org/ and here: http://en.wikipedia.org/wiki/NoSQL – ElHaix Jan 28 '14 at 17:14
  • Hi ElHaix, I've updated my question with some more information. Does that clear it up? – Tobi Jan 30 '14 at 09:15
  • With a varying schema, I would suggest a NoSQL database - take a look at Redis or ElasticSearch, both of which have a variety of .Net connectors. – ElHaix Jan 30 '14 at 14:54
  • That's not possible, MySQL is a requirement – Tobi Jan 30 '14 at 15:07
  • Instead of thinking of your tables as horizontal, with a fixed schema, you need meta data definition table that relates to a data table. For example, you may have a `MetaTable` that contains `{TableDefinitionId, ClientId, TableName, FieldName, FieldType}`. A related `DataTable` would contain the `TableDefinitionId` FK and defined something like {DataTableId, TableDefinitionId, DataValue}. To flatten out the structure, use a pivot table through EntityFramework and LINQ - http://linqlib.codeplex.com/wikipage?title=Pivot&referringTitle=Home. – ElHaix Jan 30 '14 at 16:29
  • In addition to this, I have posed the following question that you may wish to follow (http://stackoverflow.com/questions/21461607/what-is-a-good-approach-in-creating-a-non-nosql-relational-multi-schema-databas) - which will give some variations on my most-recent suggestion. – ElHaix Jan 30 '14 at 16:32
  • Hmm sounds interesting, but wouldn't that require the user to redesign or at least extent it's database? If that's the case, I'd rather avoid that, because I'd like to keep the configuration afford on the user's part at a minimum, even if that would mean more work on my part ;) – Tobi Jan 31 '14 at 08:01
  • Well if you really want a completely separate schema for each client, create a new db per client based on their XML markup or Some other config options. Keep a central data store with the connection strings, etc. – ElHaix Jan 31 '14 at 12:06
  • That's not a viable option either. You have do imagine, that a possible customer has a huge database he uses to store some identity data, users or something like that. Building a solution that would require him to redesign or change it's db in an extensive way is not acceptable. You can assume, that the db and setup on the users side as absolutly fixed. I have only control over the "other side" and I'd like to make that as flexible and userfriendly as possible while satisfying the above mentioned constraints. – Tobi Jan 31 '14 at 12:58
  • that said, I'm very thankful for your effords anyway! :) – Tobi Jan 31 '14 at 13:00
  • Don't forget to vote-up any suggestions you feel may have been helpful. – ElHaix Jan 31 '14 at 14:12
1

You can use NHibernate with MySQL, and NHibernate is a full featured ORM, where C# classess maps with your MySQL tables, and the rest will be a breeze, once you get a hang of NHibernate.

A sample is here for your reference. http://www.codeproject.com/Articles/26123/NHibernate-and-MySQL-A-simple-example

Aby
  • 1,916
  • 1
  • 12
  • 18
0

When you use the MySQL Connector/Net you can also use Entity Framework like this example from MSDN:

using (var db = new BloggingContext())
{
    // Create and save a new Blog
    Console.Write("Enter a name for a new Blog: ");
    var name = Console.ReadLine();

    var blog = new Blog { Name = name };
    db.Blogs.Add(blog);
    db.SaveChanges();
}
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
0

I have some experience with .NET <-> MySQL communication and I've used Entity Framework in the past for the communication - I had a lot of problems with it and performance issues and soon came to regret using it (this was 1-2 years ago, so may be they fixed it up). Of course, using an ORM framework adds a layer on top of your db communication which in my case proved to be not desired in terms of performance and flexibility.

Finally, I chose to take the following approach:

1) Create models with POCO classes as you would do with Entity Framework. Those models may or may not include relationships - it is up to your preference. I prefer to only add the relationships when I actually need them (so some objects may have their db relationships in the POCO's and some may not). I chose this because it lowers the complexities of when to pre-load the relationships and when not. Basically, if you don't need it - don't add it.

2) Create DAL layer (for example, using the repository pattern) that accepts and works with those objects and fires direct queries to MySQL. No EF required for this - you just need to install the Connector/NET for MySQL and you are ready to go.

A quick example of this would be the following (note: example is of the top of my head and it is just to illustrate the classes. I would use command parameters as well to prevent injection and so on):

public class Person{
  public string Name {get;set;}
}

public interface IPersonRepository{
  void AddPerson(Person p);
} 

public class PersonRepository{
  public void AddPerson(Person p){
    using(var connection = new MySqlConnection("some connection string"){
      connection.Open();

      var command  = new MySqlCommand(connection);
      command.Text = string.Format("insert into Person (Name) values ({0})", p.Name)l
      command.ExecuteNonQuery();
    }

  }
}

The benefits of this approach for me are:

  • Performance - my application need to insert large amounts of data int MySQL. Entity Framework could not cope with this. If your application doesn't handle a lot of data you might be alright with EF.

  • Flexibility - writing my own queries allows me to have better control over the communication. You can choose, for example, to use bulk inserts in MySQL (from file - really powerful and fast when you need to handle large amounts of data) for which you will need to bypass Entity Framework. I also found out that EF generates some funky queries

The main drawback is, of course, more work - you will get some things for "free" with the Entity Framework.

So, I can recommend the following:

  • Consider the amounts of data that you need to handle and make a small exercise application with those amounts. How does EF (or any other ORM) handle it? What about direct queries to the database? That will give you a somewhat accurate idea of how the communication will perform.

  • Consider how much time you have for building this application - if you are looking for a quick solution and are willing to sacrifice a bit of performance - go for EF or another ORM framework. If you have more time on your hands and would like to make a flexible solution - go for direct queries to the database.

Good luck!

sTodorov
  • 5,435
  • 5
  • 35
  • 55
  • thanks for your answer, but if I understand you correctly, I would have to hardcode the database schema in my classes. but main point in my question is, how to implement a "dynamic" schema, i.e. configurable by say an XML-File. Or did you misunderstand you? – Tobi Jan 24 '14 at 08:54
  • @Tobi, Aaah I see. I think I was wrong in interpreting your question. This is a more complicated task than just accessing communicating with the MySql database. Sorry about that. In that case, I would create a mapping layer in which you store every property that needs synchronization and you store its location in the database (that is the configurable part and you store it on an xml file). Your repository will then use the mapping layer to get the table/columns and construct the queries on the basis of those. – sTodorov Jan 24 '14 at 10:28
-1

Use Entity Framework Code First.

http://msdn.microsoft.com/en-us/data/jj193542.aspx

It is still a lot of work, but I think this is the quickest approach.

Create a C# classes according to the user and create the DB schema from those classes.

iefpw
  • 6,816
  • 15
  • 55
  • 79