.net - 我们如何在基于Dot Net的Azure移动服务中加载相关对象(预加载)?

标签 .net azure eager-loading azure-mobile-services

如果我有以下模型结构

public class QuestionItem: EntityData
{
    public string Content { get; set; }
    public bool IsAnswered { get; set; }
    public int NumberOfAnswers
    {
        //todo: make it computable
        get;
        set;
    }
    public UserItem By { get; set; }
    public string ById { get; set; }
    public string AtLocation { get; set; }
}

&父实体为

public class UserItem:EntityData
{

    public string UserName { get; set; }

    public string Gender { get; set; }

    public string BaseLocation { get; set; }

    public int Age { get; set; }

    public int Points { get; set; }

}

这确实会生成具有正确 FK 关系的数据库表。但是当查询问题项目列表时,QuestionItem.By 属性(UserItem 表的引用对象)为空。

通常这是通过在查询级别使用 .Include 方法来实现的,但我无法找到我应该在哪里执行此操作。

感谢任何帮助。

苏普雷特

最佳答案

正如 @JuneT 提到的,您需要从客户端发送 $expand header 。原因是默认情况下 Entity Framework 不会遍历对象图,因为这需要在数据库中进行联接,如果您不需要这样做,可能会对性能产生负面影响。

另一种选择,我在 this blog post 中提到过,就是在服务器端使用过滤器来为您添加该 header 。例如,使用以下属性:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
class ExpandPropertyAttribute : ActionFilterAttribute
{
    string propertyName;

    public ExpandPropertyAttribute(string propertyName)
    {
        this.propertyName = propertyName;
    }

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        base.OnActionExecuting(actionContext);
        var uriBuilder = new UriBuilder(actionContext.Request.RequestUri);
        var queryParams = uriBuilder.Query.TrimStart('?').Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries).ToList();
        int expandIndex = -1;
        for (var i = 0; i < queryParams.Count; i++)
        {
            if (queryParams[i].StartsWith("$expand", StringComparison.Ordinal))
            {
                expandIndex = i;
                break;
            }
        }

        if (expandIndex < 0)
        {
            queryParams.Add("$expand=" + this.propertyName);
        }
        else
        {
            queryParams[expandIndex] = queryParams[expandIndex] + "," + propertyName;
        }

        uriBuilder.Query = string.Join("&", queryParams);
        actionContext.Request.RequestUri = uriBuilder.Uri;
    }
}

您可以装饰您的操作以强制相关实体的扩展。

[ExpandProperty("By")]
public IQueryable<QuestionItem> GetAll() {
    return base.Query();
}

关于.net - 我们如何在基于Dot Net的Azure移动服务中加载相关对象(预加载)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23333795/

相关文章:

vb.net - 查找目录中的所有目录并仅返回名称

Azure HDInsights Spark 集群安装外部库

azure - Kubernetes Pod 使用 CPU 不超过 1m

rust - 关系的渴望

asp.net-mvc-3 - 正在延迟加载为 null 的急切加载的相关对象

c# - 如何消除 "else-if"语句

.net - RazorEngine - 命名空间导入编译错误

c# - NET 5 是否有用于存储地理定位数据的类?

azure - 如何从应用程序(客户端)ID 和目录(租户)ID 获取对象 ID?

c# - Entity Framework 多对多关系表创建 "backwards"