C# 使用EF从Azure移动服务检索父/子记录(包含列表的对象)

C# 使用EF从Azure移动服务检索父/子记录(包含列表的对象),c#,entity-framework,azure,azure-mobile-services,C#,Entity Framework,Azure,Azure Mobile Services,我有.net 4.5.2测试应用程序在Azure移动服务上运行,我正在尝试使用TableController存储数据。我的数据类型如下: public class Run:EntityData { public int RunId { get; set; } public DateTime? ActivityStarted { get; set; } public DateTime? ActivityCompleted { get; set; } public List<Lap> L

我有.net 4.5.2测试应用程序在Azure移动服务上运行,我正在尝试使用
TableController
存储数据。我的数据类型如下:

public class Run:EntityData
{
public int RunId { get; set; }
public DateTime? ActivityStarted { get; set; }
public DateTime? ActivityCompleted { get; set; }
public List<Lap> LapInformation { get; set; }

public Run()
{
    LapInformation = new List<Lap>();
}
GET /tables/Run$expand=LapInformation
// GET tables/TodoItem
[ExpandProperty("Tags")]
public IQueryable<TodoItem> GetAllTodoItems()
{
    return Query();
}
await todoTable.PullAsync("todoItems", todoTable.CreateQuery());
在我的Startup类中,我调用:

    HttpConfiguration config = new HttpConfiguration();

    new MobileAppConfiguration()
        .UseDefaultConfiguration()
        .ApplyTo(config);
在我的MobileServiceContext类中:

public class MobileServiceContext : DbContext
{
    private const string connectionStringName = "Name=MS_TableConnectionString2";

    public MobileServiceContext() : base(connectionStringName)
    {
    }

    public DbSet<Run> Runs { get; set; }
    public DbSet<Lap> Laps { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Add(
        new AttributeToColumnAnnotationConvention<TableColumnAttribute, string>(
            "ServiceTableColumn", (property, attributes) => attributes.Single().ColumnType.ToString()));
}
但是,当我
获取该对象时,我只从Run中获取字段,没有详细记录列表(Lap)。在Entity Framework中是否需要配置任何东西,以便在从DB获取运行记录时,它还获取并反序列化所有相关的详细记录

希望这是有道理的

编辑
原来它正在收回所有lap信息,但当我将其返回给客户端时,这些信息丢失了。

您可以使用带有
Include()
方法的自定义EF查询,而不是从
System.Data.Entity
命名空间获取函数的查找调用

var runs = context.Runs.Include(r => r.LapInformation)

查看一下您可以使用带有
Include()
方法的自定义EF查询,而不是从
System.Data.Entity
命名空间获取函数的查找调用

var runs = context.Runs.Include(r => r.LapInformation)

看一看

AFAIK,您还可以使用
$expand
参数来扩展集合,如下所示:

public class Run:EntityData
{
public int RunId { get; set; }
public DateTime? ActivityStarted { get; set; }
public DateTime? ActivityCompleted { get; set; }
public List<Lap> LapInformation { get; set; }

public Run()
{
    LapInformation = new List<Lap>();
}
GET /tables/Run$expand=LapInformation
// GET tables/TodoItem
[ExpandProperty("Tags")]
public IQueryable<TodoItem> GetAllTodoItems()
{
    return Query();
}
await todoTable.PullAsync("todoItems", todoTable.CreateQuery());
这是我的样品,你可以参考一下:

您可以使用自定义的
ActionFilterAttribute
标记操作,以便自动将
$expand
属性添加到查询请求中,如下所示:

public class Run:EntityData
{
public int RunId { get; set; }
public DateTime? ActivityStarted { get; set; }
public DateTime? ActivityCompleted { get; set; }
public List<Lap> LapInformation { get; set; }

public Run()
{
    LapInformation = new List<Lap>();
}
GET /tables/Run$expand=LapInformation
// GET tables/TodoItem
[ExpandProperty("Tags")]
public IQueryable<TodoItem> GetAllTodoItems()
{
    return Query();
}
await todoTable.PullAsync("todoItems", todoTable.CreateQuery());

注意:
Tags
数据是只读的,您只能更新
ToDoItem
表中的信息

此外,正如adrian hall在以下文章中提到的:

我更喜欢单独处理表和手动处理移动客户端上的关系管理。这会在移动客户端上产生更多的代码,但由于避免了大多数复杂的关系,服务器变得更加简单


好的,您还可以使用
$expand
参数按如下方式展开集合:

public class Run:EntityData
{
public int RunId { get; set; }
public DateTime? ActivityStarted { get; set; }
public DateTime? ActivityCompleted { get; set; }
public List<Lap> LapInformation { get; set; }

public Run()
{
    LapInformation = new List<Lap>();
}
GET /tables/Run$expand=LapInformation
// GET tables/TodoItem
[ExpandProperty("Tags")]
public IQueryable<TodoItem> GetAllTodoItems()
{
    return Query();
}
await todoTable.PullAsync("todoItems", todoTable.CreateQuery());
这是我的样品,你可以参考一下:

您可以使用自定义的
ActionFilterAttribute
标记操作,以便自动将
$expand
属性添加到查询请求中,如下所示:

public class Run:EntityData
{
public int RunId { get; set; }
public DateTime? ActivityStarted { get; set; }
public DateTime? ActivityCompleted { get; set; }
public List<Lap> LapInformation { get; set; }

public Run()
{
    LapInformation = new List<Lap>();
}
GET /tables/Run$expand=LapInformation
// GET tables/TodoItem
[ExpandProperty("Tags")]
public IQueryable<TodoItem> GetAllTodoItems()
{
    return Query();
}
await todoTable.PullAsync("todoItems", todoTable.CreateQuery());

注意:
Tags
数据是只读的,您只能更新
ToDoItem
表中的信息

此外,正如adrian hall在以下文章中提到的:

我更喜欢单独处理表和手动处理移动客户端上的关系管理。这会在移动客户端上产生更多的代码,但由于避免了大多数复杂的关系,服务器变得更加简单


嗯……好的,所以Include,使用一个字符串(这是Include()方法的唯一签名)返回数据。但是,它不会返回给客户端。那么这是序列化问题吗?@LDJ返回的结果是什么?一开始就不应该有任何问题。您还可以使用
System.Data.Entity
namespace.Hmmm使用其他
Include()
签名。好的,所以Include,使用字符串(这是Include()方法的唯一签名)返回数据。但是,它不会返回给客户端。那么这是序列化问题吗?@LDJ返回的结果是什么?一开始就不应该有任何问题。此外,您还可以使用
System.Data.Entity
命名空间使用其他
Include()
签名。您是否已解决此问题,是否需要进一步帮助?感谢您跟踪@Bruce MSFT。最后,我采纳了你的建议:“我更喜欢单独处理表,并在移动客户端上手动处理关系管理。这会在移动客户端上产生更多代码,但通过避免大多数复杂的关系,使服务器更加简单。”。只需独立处理父母和孩子,继续生活!:d您已经解决了这个问题,您需要进一步的帮助吗?谢谢@Bruce MSFT的跟进。最后,我采纳了你的建议:“我更喜欢单独处理表,并在移动客户端上手动处理关系管理。这会在移动客户端上产生更多代码,但通过避免大多数复杂的关系,使服务器更加简单。”。只需独立处理父母和孩子,继续生活!:D