Data Service - 5. LINQ to Data Service (2)

[ 2009-04-25 13:00:54 | 作者: yuhen ]
字号: | |
LINQ to Data Service 作为 REST URI 的一种 "变种",自然不能像 LINQ to Entities 那样支持各种复杂的操作。但对基本的查询操作还是能适应的。

1. 请求路径

在相关代码行设置断点,我们就可以在调试环境直接查看 URI。

uploads/200904/25_130106_snap1.png


DataServiceQuery<T> 继承自 DataServiceRequest,而 DataServiceRequest.ToString() 被 Override 用来输出 Request URI。
public abstract class DataServiceRequest
{
    public override string ToString()
    {
        return this.RequestUri.ToString();
    }
} 

public abstract class DataServiceQuery : DataServiceRequest, IQueryable, IEnumerable
{
}

public class DataServiceQuery<TElement> : DataServiceQuery, ...
{
    public override string ToString()
    {
        return base.ToString();
    }
}

也也就是说,我们直接通过 ToString() 来获取相应的 URI 信息。
var q = from u in context.Users select u;
var url = q.ToString();

2. 查询操作

(1) $filter
from u in context.Users where u.Id > 2 && u.Name.Contains("4") select u;

http://localhost:2394/test.svc/Users()?$filter=(Id gt 2) and substringof('4',Name)

当然,直接使用 URL 请求时,需要进行编码。

http://localhost:2394/test.svc/Users()?$filter=(Id%20gt%202)%20and%20substringof('4',Name)

ADO.NET Data Service 支持基本的算术和逻辑运算符,以及一些常用的字符串、日期 等函数,具体可参考 MSDN 帮助文档。

(2) $orderby
from u in context.Users where u.Id > 2 orderby u.Id descending select u;

http://localhost:2394/test.svc/Users()?$filter=Id gt 2&$orderby=Id desc

(3) $take & $top

分页所必须的。
(from u in context.Users select u).Skip(2).Take(3);

http://localhost:2394/test.svc/Users()?$skip=2&$top=3

在使用 First / FirstOrDefault() 时,也会转换成 $top (可以在 Host 添加 HttpModule 拦截 Request.RawUrl)。
(from u in context.Users select u).FirstOrDefault();

http://localhost:2394/test.svc/Users()?$top=1

3. 延迟载入

LINQ to Data Service 对于关联数据(导航属性) 同样采取了延迟载入。
var user = (from u in context.Users select u).FirstOrDefault();

在返回结果中,我们会看到相应的延迟信息。
{
    "d": [
        {
            "__metadata": {
                "uri": "http://localhost:2394/Test.svc/Users(1)",
                "type": "TestModel.User"
            },
            "Id": 1,
            "Name": "user1",
            "Age": 10,
            "UserDetail": {
                "__deferred": {
                    "uri": "http://localhost:2394/Test.svc/Users(1)/UserDetail"
                }
            }
        }
    ]
}

"__deferred" 和 "uri" 指示了如何进一步操作。

在 LINQ to Data Service 中,我们可以用如下两种方式获取这些 "延迟数据"。

(1) DataServiceContext.LoadProperty
var user = (from u in context.Users select u).FirstOrDefault();

context.LoadProperty(user, "UserDetail");

Console.WriteLine(user.Name);
Console.WriteLine(user.UserDetail.First().Telephone);

我们通过 HttpModule 拦截,会看到两次 GET 请求。
GET, /test.svc/Users()?$top=1
GET, /test.svc/Users(1)/UserDetail()

(2) $expand

通过 $expand 查询选项可以一次返回包含关联信息的结果。
var q = context.CreateQuery<User>("/Users")
    .AddQueryOption("$filter", "Id eq 2")
    .AddQueryOption("$expand", "UserDetail");

var user = q.First();

Console.WriteLine(user.Name);
Console.WriteLine(user.UserDetail.First().Telephone);

http://localhost:2394/test.svc/Users()?$filter=Id eq 2&$expand=UserDetail
{
    "d": [
        {
            "__metadata": {
                "uri": "http://localhost:2394/Test.svc/Users(2)",
                "type": "TestModel.User"
            },
            "Id": 2,
            "Name": "user2",
            "Age": 11,
            "UserDetail": [
                {
                    "__metadata": {
                        "uri": "http://localhost:2394/Test.svc/UserDetails(2)",
                        "type": "TestModel.UserDetail"
                    },
                    "Id": 2,
                    "Telephone": "010-10000002",
                    "User": {
                        "__deferred": {
                            "uri": "http://localhost:2394/Test.svc/UserDetails(2)/User"
                        }
                    }
                }
            ]
        }
    ]
}
[最后修改由 yuhen, 于 2009-04-25 13:15:35]
评论Feed 评论Feed: http://www.rainsts.net/feed.asp?q=comment&id=810

这篇日志没有评论。

发表评论
表情图标
[smile] [confused] [cool] [cry]
[eek] [angry] [wink] [sweat]
[lol] [stun] [razz] [redface]
[rolleyes] [sad] [yes] [no]
[heart] [star] [music] [idea]
UBB代码
转换链接
表情图标
悄悄话
用户名:   密码:  
验证码 * 请输入验证码