如何构建实体框架应用程序(使用 MEF)
本文关键字:应用程序 使用 MEF 框架 实体 构建 何构建 | 更新日期: 2023-09-27 17:56:16
我迫切地想知道如何构建我的实体框架 4(代码优先)应用程序。
我有一个 VS 项目将处理对我的数据的访问。 它是一个基于接口[IDataExport]
的MEF导出部分[MyData]
。 该项目有我的 EF 类(客户、订单等)、上下文初始值设定项等,以及所有已经像梦一样工作的东西。
有一个 VS 项目,它有我的接口(我所有的接口)。 所有项目都有对此接口项目的引用。
我有一个 VS 项目可以完成我所有的日志记录。 它也是一个基于接口[ILogging]
的MEF导出部件[MyLog]
。 该类实际上只是写入控制台。
我有三个 VS 项目,我们将它们称为 Parts(以 MEF 术语表示)。 它们是插件。 他们需要数据来工作(客户、订单等)。 实际上,他们需要同时从三个不同的表输入数据作为输入。
我有一个项目是主机应用程序。 它目前作为控制台应用程序运行,但很快就会转换为 Windows 服务。
我希望这能让你对现有的架构有一个很好的了解。 现在我在试图弄清楚如何正确进行数据访问时遇到了麻烦。
当主机需要将数据传递给插件时,它需要从 3 个不同的表中获取数据。 实际上,使用 EF 设置它的方式,将立即检索三个表。 当插件由 MEF 实例化时,如何将该数据传递给插件? 插件是否可以引发事件以与主机应用程序交互?
此外,随着插件的运行,表中的数据将需要更新。 如何将数据库中的数据向上更新三层? 主机可以调用插件,但插件无法调用主机。 只有[MyData]
项目才能访问数据库。
根据我描述的场景,有人可以告诉我如何最好地构建此应用程序吗?
更让我困惑的是,一些示例代码显示了调用应用程序(在本例中为主机),为每次搜索调用数据库启动全新的模型。
例如public List<Customer> FindCustomerList(string companyName)
{
return new CustomerManager().FindCustomerList(companyName);
}
public List<Customer> FindCustomerList(string companyName)
{
var q = from c in context.Customers
where c.CompanyName.StartsWith(companyName)
select c;
return q.ToList();
}
下面是我的三个表格。 请注意,它们具有外键关系,导致子项嵌入到主作业记录中。 就像一个有很多订单的客户。
public class pcJobAction : IVersionTracking, IpcIdentity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
//IpcIdentity
[Required]
[MaxLength(75)]
public string name { get; set; }
[MaxLength(1000)]
public string description { get; set; }
[Required]
[MaxLength(30)]
public string ServerName { get; set; }
[MaxLength(20)]
public string ServerIP { get; set; }
public int JobEnabled { get; set; }
public virtual ICollection<pcPlugInValue> PlugInText { get; set; }
//JobActions holds a list of Schedules
public virtual ICollection<pcJobSchedule> JobSchedules { get; set; }
//FK to the JobTypes table (Delete Files, Verify Backups, Ping, etc)
public long pcJobTypeId { get; set; }
public virtual pcJobType pcJobType { get; set; }
//IVersionTracking
public DateTime DateCreated { get; set; }
public DateTime LastUpdated { get; set; }
[Timestamp]
public byte[] Version { get; set; }
}
public class pcPlugInValue : IVersionTracking, IpcIdentity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
//IpcIdentity
[Required]
[MaxLength(75)]
public string name { get; set; }
[MaxLength(1000)]
public string description { get; set; }
public string PlugInText { get; set; }
public int ExecuteOrder { get; set; }
//FK to the JobAction table
public long pcJobActionId { get; set; }
public virtual pcJobAction pcJobAction { get; set; }
//FK to the codes table (to indetify the schedule type: daily, weekly, etc)
public long pcCodeId { get; set; }
public virtual pcCode pcCode { get; set; }
//IVersionTracking
public DateTime DateCreated { get; set; }
public DateTime LastUpdated { get; set; }
[Timestamp]
public byte[] Version { get; set; }
}
public class pcJobSchedule : IVersionTracking, IpcIdentity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
//IpcIdentity
[Required]
[MaxLength(75)]
public string name { get; set; }
[MaxLength(1000)]
public string description { get; set; }
//FK to the JobAction table
public long pcJobActionId { get; set; }
public virtual pcJobAction pcJobAction { get; set; }
//FK to the codes table (to indetify the schedule type: daily, weekly, etc)
public long pcCodeId { get; set; }
public virtual pcCode pcCode { get; set; }
public DateTime StartDate { get; set; }
public Boolean dayMonday { get; set; }
public Boolean dayTuesday { get; set; }
public Boolean dayWednesday { get; set; }
public Boolean dayThursday { get; set; }
public Boolean dayFriday { get; set; }
public Boolean daySaturday { get; set; }
public Boolean daySunday { get; set; }
public Boolean ThisJobIsNext { get; set; }
public DateTime EndDate { get; set; }
public int DateOfMonth { get; set; }
public int DayOfWeek { get; set; }
public DateTime ScheduleHour { get; set; }
public int EveryHowMany { get; set; }
public DateTime RunTimeLast { get; set; }
public DateTime RunTimeNext { get; set; }
//IVersionTracking
public DateTime DateCreated { get; set; }
public DateTime LastUpdated { get; set; }
[Timestamp]
public byte[] Version { get; set; }
}
从您的架构描述中,我可以假设您的主机应用程序在某处有一个 [ImportMany] 导致您的所有插件都由 MEF 实例化吗?
如果是这种情况,一种选择是(我相信您问过)将事件添加到插件接口,并从主机应用程序附加到每个插件中的该事件。 我自己也这样做了,效果很好。
如果 EF 类适合您的体系结构,另一种选择是将 EF 类放在单独的程序集中,在插件程序集中引用该程序集,并直接从插件执行数据访问。
我自己完成了第二个选项,其中我将 EF 代码优先类放入单独的程序集中,并有一些用于连接到上下文类和查询 ef 存储库的帮助程序类。但是,如果您不希望插件直接访问整个数据库,那么最好选择选项 1。特别是如果将来您决定将数据库表拆分为不同的模式,并且仅希望某些插件仅与数据库中的特定模式进行交互。