标题不太准确,但我无法想出更好的标题。
我正在尝试为MS'Forefront Identity Manager编写MySQL连接器(FIM基本上是一个同步引擎,它使用元目录同步各种数据源之间的身份)。但是我很难找到合适的设计。
假设我想将数据库中的用户数据导入到FIM的metaverse中。用户对象具有各种属性,如firstname,lastname,address等。在数据库中,这些属性可以在多个表之间分配。 FIM最终需要将这些属性合并到一个对象中。因此,用户需要配置连接器以告诉它数据如何存储在数据库中。
我想知道什么是表示此配置的“最佳”方式。有两种选择(我的):
有没有人对选择哪种替代方案以及如何解决随之而来的问题有相同的建议?或者还有另一个 - 更好 - 替代我没想到的?任何建议将不胜感激! 如果不清楚,请告诉我。
编辑:由于对用例有一些疑问,我将详细说明一下:
正如我所说,我正在为FIM开发管理代理。 FIM提供了一个所谓的可扩展连接管理代理,它基本上是一个实现一些接口的单一类。 (有关示例实现,请参阅this technet guide)。
由于我想开发一个用于管理MySQL
数据库中的身份的通用代理,我不知道编译时的数据库布局。当最终用户想要使用管理代理时,他需要决定他想要管理的身份的哪些属性。所以我需要给用户一些配置管理代理的方法。我的主要问题是,如何设计类以保存此配置。
让我们看一个简单的例子:
假设您想管理员工身份。为了简单起见,我们有三个属性:
在这个例子中,它可能是f.e.只有一个包含4列的表(属性加上一个id)。但它也可能是更好的设计,它使用两个表,一个用户表和一个部门表,使用1:1关系来定义用户部门。
FIM要求我在一个对象中合并这些属性。它提供了一个CSEntryChange
类,它有一个AttributeChanges
集合成员。然后我会创建一些AttributeChange
的实例(基本上包含属性名称及其值)并将它们添加到集合中。因此,用户可编辑的配置必须告诉管理代理如何从db 和获取具有所有已定义属性的用户如何在该数据库中创建和修改用户。
理想情况下,我有一些“MySQLSchema”类(由用户预先配置),可以返回List<CSEntryChange>
(我实际上不会使用CSEntryChange
为了解耦而使用class,但你应该得到包含db中所有用户的观点(分页可能是一个要求,但我可以在以后解决)。此外,我希望能够传递CSEntryChange
,这将导致相应的数据库条目更新(或创建,如果尚未存在)。
我希望这更清楚一点:)
答案 0 :(得分:2)
我认为您真正的问题是,“如何通过C#访问MySQL实体?”
首先,我希望您将其构建为MVC application。
我建议坚持使用完整的Microsoft堆栈,以便学习和轻松实现。
考虑到这一点,您将需要按以下步骤创建EntityFramework MySQL数据提供程序:
通过输入 Install-Package EntityFramework -Version 6.0.2 ,通过Nuget包管理器UI或包管理器控制台创建一个新项目和EntityFramework(并添加对该项目的引用)来自您的网络项目)。查看“配置EntityFramework以使用MySQL数据库”页面的一半。
通过Nuget包管理器UI或在包管理器控制台中键入 Install-Package MySql.Data.Entity ,为实体框架安装MySQL提供程序
下一步需要了解db配置更改,这些更改非常详细here - Configure EntityFramework to work with a MySQL database。
你最终应该有一个很好的类结构,它允许你通过EF遍历实体的导航属性。
根据应用程序所需的安全级别,您可能还需要创建仅包含远程调用所需数据的data transfer objects (DTOs) - 保持数据调用的有效性。
这绝不是关于如何做到这一点的明确指南,但希望能为您提供正确方向的开端。
关于您上面的第1步:
我可以保存一个合并/加入数据的选择查询,这样就可以了 结果是一个包含所有所需属性的“表”。该 这个问题是我想我必须做某种事情 解析此查询字符串以创建fim兼容模式 它(基本上是对象类型的名称(f.e。“person”)和 属性列表)。此架构需要可以从中创建 单独查询字符串而不实际执行查询(我可以 执行一些假查询,如果这会简化过程。)
我对此感到有些困惑。您是说要动态更新基于数据库模式的应用程序请求吗?
答案 1 :(得分:1)
您可以将NHibernate与MySQL一起使用,NHibernate是一个功能齐全的ORM,其中C#classess映射到您的MySQL表,其余的将是轻而易举的,一旦您掌握了NHibernate。
此处提供样本供您参考。 http://www.codeproject.com/Articles/26123/NHibernate-and-MySQL-A-simple-example
答案 2 :(得分:0)
当您使用MySQL Connector / Net时,您也可以使用Entity Framework,如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();
}
答案 3 :(得分:0)
我对.NET&lt; - &gt;有一些经验。 MySQL通信和我过去使用实体框架进行通信 - 我遇到了很多问题和性能问题,很快就后悔使用它(这是1 - 2年前,所以他们可能会修复它)。当然,使用ORM框架会在数据库通信之上添加一个层,在我的情况下,在性能和灵活性方面证明这是不可取的。
最后,我选择采用以下方法:
1)使用POCO类创建模型,就像使用Entity Framework一样。这些模型可能包括也可能不包括关系 - 这取决于您的偏好。我更喜欢在实际需要时添加关系(因此某些对象可能在POCO中有自己的db关系,有些可能没有)。我选择这个是因为它降低了何时预加载关系的复杂性,何时降低了。基本上,如果你不需要它 - 不要添加它。
2)创建接受并使用这些对象的DAL层(例如,使用存储库模式)并向MySQL发出直接查询。这不需要EF - 你只需要为MySQL安装Connector/NET就可以了。
这个的一个简单示例如下(注意:示例是我的头顶,它只是为了说明类。我也会使用命令参数来防止注入等等):
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中插入大量数据。实体框架无法应对此问题。如果您的应用程序无法处理大量数据,那么您可以使用EF。
灵活性 - 编写自己的查询可以让我更好地控制通信。例如,您可以选择在MySQL中使用批量插入(from file - 当您需要处理大量数据时非常强大且快速),您需要绕过实体框架。我还发现EF会产生一些时髦的查询
主要缺点当然是更多的工作 - 您将通过实体框架获得“免费”的一些东西。
所以,我可以推荐以下内容:
考虑您需要处理的数据量,并使用这些金额制作小型练习应用程序。 EF(或任何其他ORM)如何处理它?那么直接查询数据库怎么样?这将使您对通信的执行方式有一个准确的了解。
考虑一下构建此应用程序需要多长时间 - 如果您正在寻找快速解决方案并愿意牺牲一点性能 - 请选择EF或其他ORM框架。如果您有更多时间在手上并希望制定灵活的解决方案 - 请直接查询数据库。
答案 4 :(得分:-1)
首先使用实体框架代码。
http://msdn.microsoft.com/en-us/data/jj193542.aspx
这仍然是很多工作,但我认为这是最快捷的方法。
根据用户创建C#类,并从这些类创建数据库模式。