Как создать приложение Entity Framework (с помощью MEF) - PullRequest
2 голосов
/ 12 мая 2011

Я отчаянно пытаюсь выяснить, как спроектировать мое приложение Entity Framework 4 (сначала код).

У меня есть один проект VS, который будет обрабатывать доступ к моим данным.Это экспортированная MEF деталь [MyData], основанная на интерфейсе [IDataExport].В этом проекте есть мои EF-классы (клиент, заказ и т. Д.), Инициализатор контекста и т. Д., И все это уже работает как сон.

У меня есть один проект VS, у которого есть мои интерфейсы (все мои интерфейсы).Все проекты имеют ссылку на этот интерфейсный проект.

У меня есть один проект VS, который выполняет всю мою регистрацию.Это также экспортируемая MEF деталь [MyLog], основанная на интерфейсе [ILogging].Этот класс на самом деле просто пишет в консоль.

У меня есть три проекта VS, которые мы будем называть частями (в терминах MEF).Это плагины.Им нужны данные для работы (клиенты, заказы и т. Д.).На самом деле, им нужны данные как входные данные из трех разных таблиц одновременно.

У меня есть один проект, который является приложением Host.В настоящее время оно работает как консольное приложение, но вскоре будет преобразовано в службу 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; }
}

Ответы [ 2 ]

1 голос
/ 15 мая 2011

Могу ли я предположить, что из вашего описания архитектуры ваше хост-приложение где-то имеет [ImportMany], которое вызывает создание всех ваших плагинов с помощью MEF?

Если это так, один из вариантов(как я полагаю, вы просили) добавить событие к интерфейсам вашего плагина и прикрепить к этому событию в каждом плагине из вашего хост-приложения.Я сделал это сам, и он отлично работает.

Другой вариант, если он вписывается в вашу архитектуру, - это поместить ваши классы EF в отдельную сборку, сослаться на эту сборку в ваших сборках плагинов и получить доступ к данным.прямо из плагинов.

0 голосов
/ 10 января 2013

Я сам выполнил второй вариант, где я поместил свои классы EF code-firstclass в отдельную сборку, и у меня есть несколько вспомогательных классов, которые используются для подключения к contextclass и для запроса к репозиторию ef.Однако, если вы не хотите, чтобы ваши плагины имели прямой доступ ко всей базе данных, то, вероятно, лучше всего сделать вариант 1. Особенно, если в будущем вы решили разделить таблицы базы данных на разные схемы, и вам нужны только определенныеПлагины должны быть только для взаимодействия с определенной схемой в вашей базе данных.

...