我有.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>();
}
}
public class Lap
{
[Key]
public int LapNumber { get; set; }
public int CaloriesBurnt { get; set; }
public double Distance {get; set;}
//Some other basic fields in here
public DateTime? LapActivityStarted { get; set; }
public DateTime? LapActivityCompleted { get; set; }
public Lap()
{
}
在我的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()));
}
}
在我的控制器中,我有:
[MobileAppController]
public class RunController: TableController<Run>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
MobileServiceContext context = new MobileServiceContext();
DomainManager = new EntityDomainManager<Run>(context, Request);
}
public IList<Run> GetAllRuns()
{
var runs = context.Runs.Include("LapInformation").ToList();
return runs;
}
public SingleResult<Run> GetRun(string id)
{
return Lookup(id);
}
public async Task<IHttpActionResult> PostRun(Run run)
{
Run current = await InsertAsync(run);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
public Task DeleteRun(string id)
{
return DeleteAsync(id);
}
}
然后我可以POST
fiddler
中的201
记录,该记录以{RunId: 1234, LapInformation:[{LapNumber:1,Distance:0.8, LapActivityStarted: "2017-06-19T00:00:00", LapActivityCompleted: "2017-06-19T00:00:00", CaloriesBurnt: 12}]}
和新创建的项目的位置进行响应。我发布的数据示例如下:
GET
然而,当我''
该对象时,我只从Run中获取字段,而没有详细记录列表(Lap)。有什么我必须在实体框架中配置,以便当我从数据库获取运行记录时,它还获取并反序列化所有相关的详细记录?
希望这是有道理的。
修改 事实证明它正在拉回所有的圈数信息,但是当我将它返回给客户端时,这些信息就会丢失。
答案 0 :(得分:1)
您可以使用自定义EF查询和Include()
方法,而不是Lookup调用,最好是从System.Data.Entity
命名空间获取函数的重载。
var runs = context.Runs.Include(r => r.LapInformation)
查看https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx
答案 1 :(得分:1)
AFAIK,您还可以使用$expand
参数扩展您的收藏集,如下所示:
GET /tables/Run$expand=LapInformation
这是我的样本,您可以参考它:
您可以使用自定义ActionFilterAttribute
标记您的操作,以便自动将$expand
属性添加到您的查询请求中,如下所示:
// GET tables/TodoItem
[ExpandProperty("Tags")]
public IQueryable<TodoItem> GetAllTodoItems()
{
return Query();
}
有关详细信息,请参阅adrian hall的书chapter3 relationships。
编辑结果证明它正在撤回所有圈数信息,但当我将其返回给客户端时,该信息就会丢失。
我在移动客户端中定义了以下模型:
public class TodoItem
{
public string Id { get; set; }
public string UserId { get; set; }
public string Text { get; set; }
public List<Tag> Tags { get; set; }
}
public class Tag
{
public string Id { get; set; }
public string TagName { get; set; }
}
执行以下拉动操作后,我可以按如下方式检索标签:
await todoTable.PullAsync("todoItems", todoTable.CreateQuery());
注意:Tags
数据是只读的,您只能更新ToDoItem
表中的信息。
此外,正如Data Access and Offline Sync - The Domain Manager中提到的adrian hall:
我更喜欢单独处理表格并手动处理移动客户端上的关系管理。这会在移动客户端上产生更多代码,但通过避免大多数关系的复杂性使服务器更加简单。