将 Where() 用于 Azure 移动服务时出现问题
Problem using Where() for Azure Mobile Service
我的以下测试无效:
public class DesktopDTO
{
public DesktopDTO() {}
public DesktopDTO(string title, Guid otherId)
{
Id = Guid.NewGuid();
Title = title;
OtherId = otherId;
}
public Guid Id { get; set; }
public string Title { get; set; }
public Guid OtherId { get; set; }
}
//setup environment:
MobileServiceClient mobileService = new MobileServiceClient("http://myserver.azurewebsites.net/");
IMobileServiceSyncTable<DesktopDTO> table = mobileService.GetSyncTable<DesktopDTO>();
if (!mobileService.SyncContext.IsInitialized)
{
var store = new MobileServiceSQLiteStore("localstore1.db");
store.DefineTable<DesktopDTO>();
await mobileService.SyncContext.InitializeAsync(store);
}
DesktopDTO input = new DesktopDTO("test124", Guid.NewGuid()); //this is my entity
//invoke action:
await table.InsertAsync(input);
//check results:
List<DesktopDTO> all = await table.ToListAsync(); //this returns 1 item
DesktopDTO r1 = all.Where(x => x.Id == input.Id).FirstOrDefault(); //this returns the created item
var query12 = await table.Where(x => x.Title == "test124").ToCollectionAsync(); //this returns 1 item
DesktopDTO r = (await table.Where(x => x.Id == input.Id).ToCollectionAsync()).FirstOrDefault(); //this returns null!!
问题是最后一个本地查询使用了一个 Where()
由 Id 过滤的子句(这是 DesktopDTO
实体的 PK),return想要的实体。
实体已正确插入数据库(如其他查询所示,甚至是 "Title" 过滤的查询),所以我不明白为什么 Where()
过滤器不起作用只跟PK.
我也试过使用 LookupAsync()
方法,但还是没有结果。
我做错了什么?
谢谢!
我试着在我这边重现这个问题。但是我得到了 ArgumentException: "The id must be of type string".
如果我将 Id 类型从 Guid 更改为 string,我将无法重现您提到的问题。我这边工作正常。
public class DesktopDTO
{
public DesktopDTO() { }
public DesktopDTO(string title, Guid otherId)
{
Id = Guid.NewGuid().ToString();
Title = title;
OtherId = otherId;
}
public string Id { get; set; }
public string Title { get; set; }
public Guid OtherId { get; set; }
}
测试结果:
为了以后参考,我发现了问题。
Azure 移动服务不允许具有(本机)字段,如 GUID。但它接受 Guid 并使用大写字母将它们默默地转换为字符串。
因此,解决方案是在查询中将所有Guids都变成UPPER CASE。
您可以执行以下任一操作:
DesktopDTO r = (await table.Where(x => x.Id.ToString.ToUpper() == input.Id.ToString.ToUpper()).ToCollectionAsync()).FirstOrDefault();
或直接:
DesktopDTO r = await table.LookupAsync(id.ToString().ToUpper());
我的以下测试无效:
public class DesktopDTO
{
public DesktopDTO() {}
public DesktopDTO(string title, Guid otherId)
{
Id = Guid.NewGuid();
Title = title;
OtherId = otherId;
}
public Guid Id { get; set; }
public string Title { get; set; }
public Guid OtherId { get; set; }
}
//setup environment:
MobileServiceClient mobileService = new MobileServiceClient("http://myserver.azurewebsites.net/");
IMobileServiceSyncTable<DesktopDTO> table = mobileService.GetSyncTable<DesktopDTO>();
if (!mobileService.SyncContext.IsInitialized)
{
var store = new MobileServiceSQLiteStore("localstore1.db");
store.DefineTable<DesktopDTO>();
await mobileService.SyncContext.InitializeAsync(store);
}
DesktopDTO input = new DesktopDTO("test124", Guid.NewGuid()); //this is my entity
//invoke action:
await table.InsertAsync(input);
//check results:
List<DesktopDTO> all = await table.ToListAsync(); //this returns 1 item
DesktopDTO r1 = all.Where(x => x.Id == input.Id).FirstOrDefault(); //this returns the created item
var query12 = await table.Where(x => x.Title == "test124").ToCollectionAsync(); //this returns 1 item
DesktopDTO r = (await table.Where(x => x.Id == input.Id).ToCollectionAsync()).FirstOrDefault(); //this returns null!!
问题是最后一个本地查询使用了一个 Where()
由 Id 过滤的子句(这是 DesktopDTO
实体的 PK),return想要的实体。
实体已正确插入数据库(如其他查询所示,甚至是 "Title" 过滤的查询),所以我不明白为什么 Where()
过滤器不起作用只跟PK.
我也试过使用 LookupAsync()
方法,但还是没有结果。
我做错了什么?
谢谢!
我试着在我这边重现这个问题。但是我得到了 ArgumentException: "The id must be of type string".
如果我将 Id 类型从 Guid 更改为 string,我将无法重现您提到的问题。我这边工作正常。
public class DesktopDTO
{
public DesktopDTO() { }
public DesktopDTO(string title, Guid otherId)
{
Id = Guid.NewGuid().ToString();
Title = title;
OtherId = otherId;
}
public string Id { get; set; }
public string Title { get; set; }
public Guid OtherId { get; set; }
}
测试结果:
为了以后参考,我发现了问题。
Azure 移动服务不允许具有(本机)字段,如 GUID。但它接受 Guid 并使用大写字母将它们默默地转换为字符串。
因此,解决方案是在查询中将所有Guids都变成UPPER CASE。
您可以执行以下任一操作:
DesktopDTO r = (await table.Where(x => x.Id.ToString.ToUpper() == input.Id.ToString.ToUpper()).ToCollectionAsync()).FirstOrDefault();
或直接:
DesktopDTO r = await table.LookupAsync(id.ToString().ToUpper());