如何在C#中表示MySQL数据库模式?

标题不是那么准确,但我无法想出更好的标题。

我正在尝试为MS的Forefront Identity Manager编写MySQL连接器(FIM基本上是一个同步引擎,它使用元目录同步各种数据源之间的身份)。 但是我很难找到合适的设计。

假设我想将数据库中的用户数据导入到FIM的metaverse中。 用户对象具有各种属性,如firstname,lastname,address等。在数据库中,这些属性可以在多个表之间分配。 FIM最终需要将这些属性合并到一个对象中。 因此,用户需要配置连接器以告诉它数据如何存储在数据库中。

我想知道什么是代表这种配置的“最佳”方式。 有两种选择(我的):

  1. 我可以保存一个合并/连接数据的选择查询,这样结果就是一个包含所有所需属性的“表”。 这个问题是我认为我必须对这个查询字符串进行某种解析,以便从中创建一个fim兼容模式(基本上是对象类型的名称(fe“person”)和属性列表)。 这个模式需要单独从查询字符串创建而不实际执行查询(如果这样可以简化过程,我可以执行一些假查询)。
  2. 我可以创建一些类来表示数据库模式,即表和关系。 由于我不熟悉MySQL(或根本就没有数据库),我冒着错过一些特殊情况的风险。 此外,它可能是某种矫枉过正,因为一旦配置了架构,就可以假设它是固定的。

有没有人对选择哪种替代方案以及如何解决随之而来的问题有相同的建议? 还是有另一个 – 更好 – 替代我没想到的? 任何建议将不胜感激! 如果不清楚,请告诉我。

编辑 :由于对用例有一些问题,我将详细说明:

正如我所说,我正在为FIM开发管理代理。 FIM提供了一个所谓的可扩展连接管理代理,它基本上是一个实现一些接口的单一类。 (有关示例实现,请参阅此technet指南 )。

由于我想开发一个用于管理MySQL数据库中的身份的通用代理,我不知道编译时的数据库布局。 当最终用户想要使用管理代理时,他需要决定他想要管理的身份的哪些属性。 所以我需要给用户一些配置管理代理的方法。 我的主要问题是,如何设计类以保存此配置。

让我们看一个简单的例子:

假设您想要管理员工身份。 为了简单起见,我们有三个属性:

  • 名字
  • 部门

在这个示例中,它可能只是一个包含4列的单个表(属性加上一个id)。 但它也可以是更好的设计,它使用两个表,一个用户表和一个部门表,使用1:1关系来定义用户部门。

FIM要求我在一个对象中合并这些属性。 它提供了一个CSEntryChange类,它有一个AttributeChanges集合成员。 然后我会创建一些AttributeChange实例(它基本上包含属性名称和它的值)并将它们添加到集合中。 因此,用户可编辑的配置必须告诉管理代理如何从db获取具有所有已定义属性的用户以及如何在该数据库中创建和修改用户。

理想情况下,我有一些“MySQLSchema”类(由用户预先配置),可以返回List (我实际上不会为了解耦而使用CSEntryChange类,但是你应该得到包含db中所有用户的观点(分页可能是一个要求,但我可以稍后解决)。 此外,我希望能够传递一个CSEntryChange ,这将导致相应的数据库条目更新(或创建,如果尚未存在)。

我希望这清楚一点:)

我认为你真正的问题是,“ 如何通过C#访问MySQL实体?

首先,我希望您将其作为MVC应用程序构建。

为了学习和易于实现,我建议坚持使用完整的Microsoft堆栈。

考虑到这一点,您将需要按以下步骤创建EntityFramework MySQL数据提供程序:

  1. 通过键入Install-Package EntityFramework -Version 6.0.2 (并从Web项目添加对此项目的引用),通过Nuget包管理器UI或包管理器控制台创建新项目和EntityFramework。 查看“配置EntityFramework以使用MySQL数据库”页面的一半。

  2. 通过Nuget包管理器UI或在包管理器控制台中键入Install-Package MySql.Data.Entity ,为entity framework安装MySQL提供程序

下一步需要了解db配置更改, 这里有详细说明- 配置EntityFramework以使用MySQL数据库 。

您最终应该有一个很好的类结构,它允许您通过EF遍历实体的导航属性。

根据应用程序所需的安全级别,您可能还需要创建仅包含远程调用所需数据的数据传输对象(DTO) – 保持数据调用的有效性。

这绝不是如何做到这一点的明确指南,但希望能为您提供正确方向的开端。

关于您上面的步骤#1:

我可以保存一个合并/连接数据的选择查询,这样结果就是一个包含所有所需属性的“表”。 这个问题是我认为我必须对这个查询字符串进行某种解析,以便从中创建一个fim兼容模式(基本上是对象类型的名称(fe“person”)和属性列表)。 这个模式需要单独从查询字符串创建而不实际执行查询(如果这样可以简化过程,我可以执行一些假查询)。

我有点困惑。 您是说要动态更新基于数据库模式的应用程序请求?

您可以将NHibernate与MySQL结合使用,NHibernate是一个function齐全的ORM,其中C#classess映射到您的MySQL表,其余的将是轻而易举的,一旦您掌握了NHibernate。

这里有一个样本供您参考。 http://www.codeproject.com/Articles/26123/NHibernate-and-MySQL-A-simple-example

当您使用MySQL Connector / Net时,您也可以像MSDN中的此示例一样使用Entity Framework :

 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(); } 

我有一些.NET < - > MySQL通信的经验,我过去使用Entity Framework进行通信 – 我遇到了很多问题和性能问题,很快就后悔使用它(这是1-2几年前,他们可能会修复它。 当然,使用ORM框架会在数据库通信之上添加一个层,在我的情况下,在性能和灵活性方面certificate这是不可取的。

最后,我选择采用以下方法:

1)使用POCO类创建模型,就像使用Entity Framework一样。 这些模型可能包含也可能不包含关系 – 这取决于您的偏好。 我更喜欢只在实际需要时添加关系(所以有些对象可能在POCO中有自己的db关系,有些可能没有)。 我选择这个是因为它降低了何时预加载关系的复杂性,何时降低了。 基本上,如果你不需要它 – 不要添加它。

2)创建接受并使用这些对象的DAL层(例如,使用存储库模式)并向MySQL发出直接查询。 这不需要EF – 你只需要安装Connector / NET for MySQL就可以了。

一个简单的例子如下(注意:示例是我的头顶,它只是为了说明类。我也会使用命令参数来防止注入等):

 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(); } } } 

这种方法对我的好处是:

  • 性能 – 我的应用程序需要在MySQL中插入大量数据。 entity framework无法应对此问题。 如果您的应用程序不能处理大量数据,那么EF可能没问题。

  • 灵活性 – 编写我自己的查询可以让我更好地控制通信。 例如,您可以选择在MySQL中使用批量插入( 从文件 – 当您需要处理大量数据时非常强大且快速),您需要绕过entity framework。 我还发现EF会产生一些时髦的查询

当然,主要的缺点是更多的工作 – 您将通过entity framework获得“免费”的一些东西。

所以,我可以推荐以下内容:

  • 考虑您需要处理的数据量,并使用这些金额制作小型练习应用程序。 EF(或任何其他ORM)如何处理它? 那么直接查询数据库怎么样? 这将使您对通信的执行方式有一个准确的了解。

  • 考虑一下你有多少时间来构建这个应用程序 – 如果你正在寻找一个快速的解决方案,并愿意牺牲一点性能 – 去EF或其他ORM框架。 如果您有更多时间在手上并希望制定灵活的解决方案 – 请直接查询数据库。

祝好运!

首先使用实体​​框架代码。

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

它仍然是很多工作,但我认为这是最快的方法。

根据用户创建C#类,并从这些类创建数据库模式。