使用OData / Entity Framework的空导航属性

时间:2012-02-29 20:47:38

标签: c# linq entity-framework ado.net linq-to-entities

我有一个数据库模式(MySql)公开为我的Silverlight客户端使用Linq查询的数据/ OData服务。这是有问题的模型: enter image description here

列Level和Application是Int值,通过外键引用表lookuplevel和lookuppid。

因此, logstest 表中的条目可能如下所示:

ID:35
Date: 2012-02-29
Level: 1
Application: 1
Message: MyMessage
Exception: MyException
ReverseOrder: 56 (don't mind this column)

我们可以使用 lookuplevel

ID: 1
String: Warning

并在 lookuppid

ID: 1
String: Product A

如您所见,Level和Application列实际上映射到引用表中的值。

现在客户端(Silverlight),我通过linq查询获取 logstest 表的内容。

public void LoadErrors()
{
   var linqQuery = (from e in _myEntities.logstests
                    select e);

   AsyncCallback GetDataComplete = new AsyncCallback(MyCallback);
           ((DataServiceQuery<logstest>)linqQuery).BeginExecute(GetDataComplete, linqQuery);
}

private void MyCallback(IAsyncResult asyncResult)
{
    DataServiceQuery<logstest> query = asyncResult.AsyncState as DataServiceQuery<logstest>;

    foreach (logstest error in e.Query.EndExecute(e.Result))
    {
        Error newError = new Error
        {
            Date = error.Date,
            Level = error.lookuplevel.String,
            Application = error.lookuppid.String,
            Message = error.Message,
            Exception = error.Exception
        };
    }

    // Do more stuff...
}

错误是在数据网格上绑定的自定义类,它在单独的列中显示每个字段。

显然,对于列Level和Application,我不想显示它们引用的值的索引,而是显示值本身(即:对于Level I想要显示Warning而不是1)。

问题是 error.lookuplevel error.lookuppid 都为空,我不知道为什么。 在某处我不知道有什么问题吗?

提前致谢!

3 个答案:

答案 0 :(得分:2)

您必须明确要求包含相关实体,否则WCF DS客户端将不会在服务器上请求它。并且它也不会延迟加载导航属性,因为延迟加载必须调用HTTP请求,这可能需要很长时间,因此在属性getter中执行此操作并不是一个好主意。

要求包含相关实体,您需要在查询中添加$ expand,如下所示:

var linqQuery = (from e in 
   _myEntities.logstests.Expand("lookuppid").Expand("lookuplevel")  
   select e); 

答案 1 :(得分:0)

通常在EF中如果您没有在上下文中启用延迟加载,则需要在查询中按名称包含导航属性:

var linqQuery = (from e in
   _myEntities.logstests.Include("lookuppid").Include("lookuplevel") 
   select e);

答案 2 :(得分:0)

请从http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=8363安装EF 4.1以停止在Include中使用魔术字符串。添加

using System.Data.Entity;

到你的使用陈述。

然后编写以下查询:

var linqQuery = _myEntities.logstests.Include(e=>e.lookuppid).Include(e=>e.lookuplevel);

有关更多信息,请参阅以下http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx