如何改进实体框架和Javascript交互

Sam*_*Sam 11 .net c# ajax entity-framework

这是一个非常模糊/主观的问题.我想知道这是否是使用ajax调用向/从浏览器发送/检索数据的最佳方式.在后端webservice上,我想使用实体框架.以下是两个示例函数.

"最佳"的标准是编写代码的速度,可读代码和健壮的体系结构.

感谢您提供任何反馈,建议和意见.

获得功能

[WebMethod]
public AjaxEmployee EmployeeGetById(int employeeID, bool getTimeOff)
{
    using (Time_TrackerEntities ctx = new Time_TrackerEntities())
    {
        var results = from item in ctx.Employees
                      where item.ID == employeeID
                      orderby item.Last_Name
                      select new AjaxEmployee
                      {
                          ID = item.ID,
                          Employee_ID = item.Employee_ID,
                          First_Name = item.First_Name,
                          Middle_Name = item.Middle_Name,
                          Last_Name = item.Last_Name,
                          Supervisor_ID = item.Supervisor_ID,
                          Active = item.Active,
                          Is_Supervisor = item.Is_Supervisor
                      };
        var emp = results.FirstOrDefault();
        if (getTimeOff)
        {
            var results2 = from item2 in ctx.Time_Off
                           where item2.Employee_ID == emp.Employee_ID
                           select new AjaxTime_Off
                           {
                               ID = item2.ID,
                               Employee_ID = item2.Employee_ID,
                               Date_Off = item2.Date_Off,
                               Hours = item2.Hours
                           };
            emp.Time_Off = results2.ToList<AjaxTime_Off>();
        }

        return emp;
    }
}
Run Code Online (Sandbox Code Playgroud)

保存功能

[WebMethod]
public bool EmployeeSave(AjaxEmployee emp)
{
    using (Time_TrackerEntities ctx = new Time_TrackerEntities())
    {
        var results = from item in ctx.Employees
                      where item.ID == emp.ID
                      select item;

        var myEmp = results.FirstOrDefault();
        if (myEmp == null)
        {
            myEmp = new Employee();
            ctx.Employees.AddObject(myEmp);
        }

        myEmp.Employee_ID = emp.Employee_ID;
        myEmp.First_Name = emp.First_Name;
        myEmp.Middle_Name = emp.Middle_Name;
        myEmp.Last_Name = emp.Last_Name;
        myEmp.Supervisor_ID = emp.Supervisor_ID;
        myEmp.Active = emp.Active;
        myEmp.Is_Supervisor = emp.Is_Supervisor;

        return ctx.SaveChanges() > 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

RPM*_*984 9

有一些改进.

Save()方法 - 不要从左到右复制,使用EF内置逻辑

而不是这个:

myEmp.Employee_ID = emp.Employee_ID;
myEmp.First_Name = emp.First_Name;
myEmp.Middle_Name = emp.Middle_Name;
myEmp.Last_Name = emp.Last_Name;
myEmp.Supervisor_ID = emp.Supervisor_ID;
myEmp.Active = emp.Active;
myEmp.Is_Supervisor = emp.Is_Supervisor;
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

ctx.Employees.ApplyCurrentValues(emp).

这样做,就是在图中查找具有相同键的实体(因为您刚刚检索到它FirstOrDefault()),并使用您传入的实体覆盖标量值 - 这正是您所做的.

因此,如果添加任何额外的标量属性,您的7行将变为1,您将不必重构代码.请记住 - 仅适用于标量属性,而不适用于导航属性.

为什么要构建主键检索查询?只需对SingleOrDefault()使用谓词

而不是这个:

var results = from item in ctx.Employees
              where item.ID == emp.ID
              select item;

var myEmp = results.FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

做这个:

var myEmp = ctx.Employees.SingleOrDefault(x => x.ID == emp.Id);
Run Code Online (Sandbox Code Playgroud)

或者甚至更好,使用管道/过滤技术:

var myEmp = ctx.Employees.WithId(emp.Id).SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)

其中WithId是一种IQueryable<Employee>扩展方法,该滤波器基于所提供的雇员ID查询.这允许从存储库/ DAL中分离过滤/业务逻辑.它应该放在你的域模型中,这样你就可以有一个很好的流畅API来通过你的ORM查询你的域实体.

当您通过主键检索实体时,您应该始终使用SingleOrDefault()or Single(),never FirstOrDefault()First().如果它是一个主键 - 它应该只有一个,所以你应该抛出一个异常,如果存在多个,这就是SingleOrDefault()它.正如@Shiraz所提到的那样 - 你的FirstOrDefault()意志会崩溃下面的查询.使用时总是需要空检查<First/Single>OrDefault().

可以对Get方法进行相同的改进.

总的来说,您的代码没有任何功能上的错误 - 它只需要微妙的改进,空检查和异常处理.

我强烈建议的唯一功能改进是将您的Web服务代码重构为通用存储库.因为代码非常简单,可以在任何实体中重复使用.Web服务不应该关注事务,主键或EF逻辑.它甚至不应该引用EF DLL.将此逻辑封装在存储库后面并将持久性逻辑委托给那里(当然通过接口).

完成上面提到的更改后,您的Web服务方法每行不应超过5-7行代码.

你的网络服务中有太多的智能 - 它应该是愚蠢和持久的无知.