在REST/WCF服务中将数据集从LINQ返回到SQL

BDW*_*BDW 5 linq wcf

我有一个WCF/REST Web服务,我正在考虑使用Linq to SQL从中返回数据库信息.

对表和返回行进行基本查询很容易,例如:

    [WebGet(UriTemplate = "")]
    public List<User> GetUsers()
    {
        List<User> ret = new List<User>(); ;
        using (MyDataContext context = new MyDataContext())
        {
            var userResults = from u in context.Users select u;
            ret = userResults.ToList<User>();
        }

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

但是,如果我想从多个表中返回数据或者与表的模式不完全匹配,该怎么办?我无法弄清楚如何从此查询返回结果,例如:

 var userResults = from u in context.Users
   select new  { u.userID, u.userName, u.userType, 
                 u.Person.personFirstname, u.Person.personLastname };
Run Code Online (Sandbox Code Playgroud)

显然,生成的行集不符合"用户"架构,因此我不能只转换为User对象列表.

我尝试在对象模型中创建一个与结果集相关的新实体,但它不想进行转换.

我错过了什么?

编辑:相关问题:存储过程返回的结果如何?同样的问题,将它们打包以通过服务返回的最佳方法是什么?

Ste*_*kes 5

一般来说,您不应该从服务返回域对象,因为如果您这样做,您将遇到类似您正在查找的问题.域对象旨在描述问题域中的特定实体,并且通常不能很好地适合提供从服务调用返回的特定数据集.

您最好将域实体与服务分离,方法是创建数据传输对象来表示它们,这些对象仅包含您需要传输的信息.DTO将具有构造函数,这些构造函数接受域对象并复制所需的任何属性值(您还需要无参数构造函数以便它们可以序列化),或者您可以使用像AutoMapper这样的对象 - 对象映射器.它们还具有特定于服务的功能,如IExtensibleDataObjectDataMemberAttributes,它们不适用于域对象.这使您的域对象可以独立于您从服务发送的对象而变化.


Eug*_* S. 4

您可以创建一个复杂类型,而不是返回匿名对象,而是返回复杂类型。当您使用函数导入映射存储过程时,您可以选择自动创建复杂类型。

使用您需要的属性创建自定义类:

public class MyTimesheet
{
    public int Id { get; set; }
    public string Data { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后从 Linq 查询创建它:

using (linkDataContext link = new linkDataContext())
{
    var data = (from t in link.TimesheetDetails
               select new MyTimesheet
               {
                   Id = t.Id,
                   Data = t.EmployeeId.ToString()
               }).ToList();
}
Run Code Online (Sandbox Code Playgroud)