Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to architect Entity Framework Application (with MEF)
    primarykey
    data
    text
    <p>I am desperate to find out how to architect my Entity Framework 4 (code first) application.</p> <p>I have one VS project that will handle access to my data. Its a MEF-Exported Part <code>[MyData]</code>, based on an Interface <code>[IDataExport]</code>. That project has my EF classes (customer, order, etc), the context initializer, etc and all that already works like a dream.</p> <p>I have one VS project that has my interfaces (all my interfaces). All projects have a reference to this Interface project.</p> <p>I have one VS project that does all my logging. It is also a MEF-Exported Part <code>[MyLog]</code>, based on an interface <code>[ILogging]</code>. That class really just writes to the Console.</p> <p>I have Three VS projects that we will call Parts (in MEF terms). They are plugins. They need data to work (customers, orders, etc). Actually, they need data as an Input from three different tables, all at once.</p> <p>I have one project that is the Host application. It is currently running as a console application but will soon be converted to a Windows Service.</p> <p>I hope that gave you a good idea of the architecture that is in place. Now I am having troubles trying to figure out how to do my data access correctly. </p> <p>When the host needs data to pass to the plugins, it needs to get data from 3 different tables. Actually, the way it is setup with EF, the three tables will be retrieved at once. How do I pass that data to the plug-in, when the plugin was instantiated by MEF? Can Plug-Ins raise events to interact with the Host application? </p> <p>In addition, as the plug-ins run, data in the tables will need to be updated. How do I keep my data in the database updated three layers up? The Host can call the Plug-In, but the Plugin doesn't have a way to call the Host. Only the <code>[MyData]</code> project has access to the Database.</p> <p>Based on the scenario that I described, could someone please tell me how to best architect this application?</p> <p>Adding further to my confusion, some sample code shows the calling application (in this case the host), starting brand new Models for each search call to the database. e.g.</p> <pre><code>public List&lt;Customer&gt; FindCustomerList(string companyName) { return new CustomerManager().FindCustomerList(companyName); } public List&lt;Customer&gt; FindCustomerList(string companyName) { var q = from c in context.Customers where c.CompanyName.StartsWith(companyName) select c; return q.ToList(); } </code></pre> <hr> <p>Below are my three tables. Please note that they have foreign key relationships, resulting in sub-items being embedded inside of the main job record. Like a customer with many orders.</p> <pre><code>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&lt;pcPlugInValue&gt; PlugInText { get; set; } //JobActions holds a list of Schedules public virtual ICollection&lt;pcJobSchedule&gt; 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; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload