我已经建立了SQL Server数据库设置。然后,我在控制台应用程序中生成了一个实体框架模型,以测试一些选择,编辑和添加到数据库。一切顺利。
我现在正朝着我的WinForms和WebApp的最终物理设计迈进。所以,我决定在单独的项目中完成这个项目。我将实体框架移动到数据项目,我创建了一个服务项目,我仍然将我的控制台应用程序作为测试应用程序(所有在同一解决方案中)。
我有一个ClassLib,数据传输对象可以在我的图层之间传递。所以我的GUI层和服务层不知道实体框架。我的EF项目中有辅助方法,可以将EF数据转换为List等...
例如辅助方法:
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方法......然后传递一个List&lt;&gt;子对象,以及保存方法的单个Parent类...然后将Dtos转换为EF模型,然后以这种方式保存它?
这是一个可接受的计划吗?
答案 0 :(得分:3)
我只使用DTO对象将数据从A传输到B.更新,添加,删除等,我总是封装在命令(命令模式)中。 检索数据我使用“助手”类同样进行。
命令模式示例:
基类:
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();