2011-05-12 83 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.特別是如果將來您決定將數據庫表分成不同的模式,並且只希望某些插件只能與數據庫中的特定模式進行交互。