2011-05-12 63 views
2

我迫切需要了解如何构建我的实体框架4(代码优先)应用程序。如何构建实体框架应用程序(使用MEF)

我有一个VS项目,将处理我的数据访问。其MEF导出部分[MyData],基于接口[IDataExport]。该项目有我的EF类(客户,订单等),上下文初始化程序等,所有这些已经像梦一样运作。

我有一个VS项目,有我的接口(我所有的接口)。所有项目都有对这个接口项目的参考。

我有一个VS项目,做我所有的日志记录。它也是基于界面[ILogging]的MEF导出部分[MyLog]。该类真的只是写入控制台。

我有三个VS项目,我们将调用Parts(MEF术语)。他们是插件。他们需要数据才能工作(客户,订单等)。实际上,他们需要将数据作为来自三个不同表格的输入,一次完成。

我有一个项目是主机应用程序。它目前作为控制台应用程序运行,但很快会转换为Windows服务。

我希望能给你提供一个很好的建筑架构。现在我遇到了麻烦,想要弄清楚如何正确地进行数据访问。

当主机需要数据传递给插件时,它需要从3个不同的表中获取数据。实际上,它与EF设置的方式一样,三个表将被一次检索。当插件由MEF实例化时,如何将这些数据传递给插件?插件能否引发事件与Host应用程序交互?

此外,随着插件的运行,表中的数据将需要更新。如何让我的数据更新三层数据库?主机可以调用插件,但插件无法调用主机。只有[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; } 
} 
+0

使用与您使用的结构相同的结构,如果它是SQL数据库并从那里开始工作 – soandos 2011-05-12 03:29:06

+0

我不确定这会起作用。这是实体框架(一个完全不同的野兽)。我有对象,我有本地数据,我有同步,我有ClientWins,我有ServerWins等,等等。 – s0ftimage 2011-05-12 03:35:57

+0

它们在实现时通常不相似,但流程通常类似(在我有限的经验中)。 – soandos 2011-05-12 03:37:53

回答

1

从你的架构描述,我可以假设你的主机应用程序,某个地方,一个[ImportMany],导致所有的插件由MEF被实例化?

如果是这样的话,一个选项是(因为我相信你问过)将一个事件添加到你的插件接口,并附加到你的主机应用程序的每个插件中的事件。我自己做到了,并且工作正常。

如果它适合你的架构,另一个选择是将你的EF类放在一个单独的程序集中,在你的插件程序集中引用该程序集,并直接从插件中访问你的数据。

0

我已经完成了第二个选项,我已经将我的EF代码firstclasses放入单独的程序集中,并且有一些帮助程序类用于连接到contextclass,并查询ef存储库。 但是,如果您不希望插件可以直接访问整个数据库,那么可能最好做的选择1.特别是如果将来您决定将数据库表分成不同的模式,并且只希望某些插件只能与数据库中的特定模式进行交互。

相关问题