2011-01-08 2 views
1

У меня установленная база данных SQL Server. Затем я сгенерировал модель Entity Framework в Консольном приложении для проверки выбора, редактирования и добавления в базу данных. Все прошло хорошо.Entity Framework для разных проектов - экономия?

Теперь я перехожу к своему окончательному физическому дизайну своих WinForms и WebApp. Итак, я решил сделать проект в отдельных проектах. Я переместил Entity Framework в проект Data, я создал проект Services, и у меня все еще есть консольное приложение в качестве тестового приложения (все в том же решении).

У меня есть ClassLib с объектами передачи данных, которые могут проходить между моими слоями. Таким образом, мой уровень графического интерфейса и уровень сервиса не знают об объектной структуре. У меня есть вспомогательные методы в моей EF проекта, которые преобразуют данные EF в список и т.д. ...

Eg метода хелперов:

using ClassLib; 

namespace Data 
{ 
    public class PayeeDAL : EntityBase 
    { 

    public static List<PayeeDto> GetPayees() 
    { 
     var payees = (from payee in Db.payees 
         select payee).ToList(); 

     List<PayeeDto> reply = new List<PayeeDto>(); 

     foreach (var pa in payees) 
     { 
      PayeeDto p = new PayeeDto 
          { 
           PayeeId = pa.payee_id, 
           Name = pa.name, 
           Deleted = pa.deleted == null 
          }; 
      reply.Add(p); 
     } 
     return reply; 

    } 
} 
} 

И мой объект передачи данных выглядит следующим образом:

namespace ClassLib 
{ 
    public class PayeeDto 
    { 
     public int PayeeId { get; set; } 
     public string Name { get; set; } 
     public bool Deleted { get; set; } 
    } 
} 

Итак, мой выбор хорошо работает с этим дизайном ... но ... не знаю, как справиться с сохранением.

В моем консольном приложении, когда EF был доступен для меня, я сделал это:

     db.AddToaccount_transaction(ac); 

        account_transaction_line atl = new account_transaction_line 
        { 
         amount = amount, 
         cost_centre = 
          db.cost_centre.FirstOrDefault(
           cc => cc.cost_centre_id == costcentreid), 
         sub_category = 
          db.sub_category.First(
           sc => sc.sub_category_id == subcategoryId), 
         account_transaction = ac, 
         budget = db.budgets.FirstOrDefault(b => b.budget_id == budgetid) 

        }; 

        db.AddToaccount_transaction_line(atl); 


       } 



       db.SaveChanges(); 

Но теперь у меня нет доступа к .AddTo .... и .SaveChanges ... В мое консольное приложение, я бы создавал родительский объект, а затем добавлял несколько дочерних объектов ... а затем добавлял дочерние объекты к родительскому объекту и сохранял.

Но как это будет сделано в моей новой структуре? Я думаю, что у меня будет метод Save в каждом из моих вспомогательных классов ... И затем передайте список <> дочерних объектов вместе с одним классом родителя для метода сохранения ... и затем преобразуйте Dtos для моделей EF, а затем сохранить их таким образом?

Это приемлемый план?

ответ

3

Я использую объекты DTO для передачи данных от A до B. Обновление, добавление, удаление и т. Д., Я всегда инкапсулирую в Commands (Command Pattern). Извлечение данных Я делаю аналогично с классами «Помощник».

Пример команда:

Базовые классы:

namespace Busker.Data.Commands 
{ 
    /// <summary> 
    /// The 'Command' abstract class 
    /// </summary> 
    public abstract class Command 
    { 

     private string message = ""; 
     public string Message 
     { 
      get { return message; } 
      set { message = value; } 
     } 


     private bool success = false; 
     public bool Success 
     { 
      get { return success; } 
      set { success = value; } 
     } 

     private Validator validator = new Validator(); 
     public Validator Validator 
     { 
      get { return validator; } 
      set { validator = value; } 
     } 

     private CommandStatusCode statusCode = CommandStatusCode.OK; 
     public CommandStatusCode StatusCode 
     { 
      get { return statusCode; } 
      set { statusCode = value; } 
     } 

     public LoggingLevel LoggingLevel = LoggingLevel.Debug; 


     //public BuskerContext BuskerContext; 


     public bool IsValid() 
     { 
      if (validator.Errors.Count > 0) 
       return false; 
      return true; 

     } 

     public abstract void Execute(); 

     public void FailedSubCommand(Command cmd) 
     { 
      this.Success = cmd.Success; 
      this.Message = cmd.message; 
     } 
    } 
} 


namespace Busker.Data.Commands 
{ 
    public class Invoker 
    { 
     private Command command; 

     public Command Command 
     { 
      get { return command; } 
      set { command = value; } 
     } 


     public void SetCommand(Command command) 
     { 
      this.Command = command; 
     } 

     public virtual void ExecuteCommand() 
     { 
      if (command == null) 
       throw new Exception("You forgot to set the command!!"); 

      try 
      { 
       log(this.command.GetType().Name + " starting execution "); 
       command.Execute(); 
       if (!command.Success) 
       { 
        log(this.command.GetType().Name + " completed execution but failed. Message: " + command.Message + " " + command.StatusCode.ToString()); 
       } 
       else 
        log(this.command.GetType().Name + " completed execution. Success!"); 

      } 
      catch (Exception ex) 
      { 
       command.StatusCode = CommandStatusCode.Error; 
       Loggy.AddError("An unhandled error was caught in " + this.command.GetType().Name + ": " + ex.Message, ex); 
       command.Message = ex.ToString(); 
       //throw; 
      } 
     } 

     private void log(string msg) 
     { 
      switch (command.LoggingLevel) 
      { 
       case Busker.Data.Constants.LoggingLevel.Debug: 
        Loggy.Debug(msg); 
        break; 
       case Busker.Data.Constants.LoggingLevel.Off: 
        break; 
       default: 
        Loggy.Add(msg); 
        break; 

      } 

     } 

     public virtual void ExecuteLinqCommand() 
     { 
      this.ExecuteCommand(); 
     } 
    } 
} 

namespace Busker.Data.Commands 
{ 
    public static class Extensions 
    { 
     /// <summary> 
     /// Executes the command using the default invoker. 
     /// </summary> 
     /// <param name="aCommand"></param> 
     public static void Invoke(this Command aCommand) 
     { 
      System.Diagnostics.StackTrace stackTrace = new System.Diagnostics.StackTrace(); 
      System.Reflection.MethodBase m = stackTrace.GetFrame(1).GetMethod(); 
      String strMethodName = m.DeclaringType.Name + "." + m.Name; 

      try 
      { 
       Invoker invoker = new Invoker(); 
       invoker.SetCommand(aCommand); 
       invoker.ExecuteCommand(); 
      } 
      catch (Exception ex) 
      { 
       Loggy.AddError("An error occured in Extensions.Invoke. + " + strMethodName ,ex); 
       throw ex; 
      } 

     } 
} 

Реализация Пример:

namespace Busker.Data.Commands.Message 
{ 
    public class CreateMessageCommand :Command 
    { 


     public CreateMessageCommand (int from, int to, string title, string body) 
     { 
       // set private variable.. 
     } 


     public override void Execute() 
     { 

      // Do your stuff here 


      be.SaveChanges(); 
      this.Success = true; 

     } 
    } 
} 

Использование:

CreateMessageCommand cmd = new CreateMessageCommand (...); 
//Don't use the execute method of the command 
//the invoker, because implemented as an extension can be exchange in different 
//environments 
cmd.Invoke(); 
+0

Это было бы здорово, если бы вы Коула показать пример. Благодарю. – Craig

+0

отредактировал мой ответ, надеюсь, что ничего не забыл .. – AyKarsi

+0

Я не совсем понимаю - поэтому я искал больше и наткнулся на учебник, в котором показывался человек, делающий приложение EF, используя консольное приложение. Она ссылалась на проект EF непосредственно из консольного приложения. Это все легко, но ... это кажется неправильным. Разумеется, должен быть сервисный уровень, и никакого взаимодействия между проектом GUI и проектом EF, не так ли? – Craig

Смежные вопросы