我有xamarin表单应用程序。我使用odata简单客户端来操作app数据库。
我正在尝试将数据添加到多对多表中。
这是我的第一个实体
public class Genre : BaseGenre
{
List<User> Users { get; set; }
}
而我的另一个
public class User : BaseUser
{
List<Genre> Genres { get; set; }
}
这就是我试图链接它们的功能
public async void AddGenresAsnyc(User u, List<Genre> Genres)
{
u.Genres = Genres;
try {
//await client.For<User> (CollectionName).Key(u).LinkEntryAsync(us => us.Genres, Genres);
await client.For<User> (CollectionName).Key(u.id).Set(u).UpdateEntriesAsync();
} catch (Exception e) {
Exception ex = e;
}
}
第一个,linkentryasync抛出异常
参数数量与预期计数不符。
第二个抛出
未找到[Genre]类型的链接集合
任何帮助都会很棒。我被困在工作中。提前谢谢。
答案 0 :(得分:1)
您需要更改的一件事是将属性Genre.Users和User.Genres公开。 Simple.OData.Client使用反射来分配属性值,并且无法为私有属性/字段分配值。我使用您发送给我的架构测试了您的代码,只要属性是公开的,请求就会完成。
关于下一个示例(使用LinkEntryAsync),如果要在单个调用中更新链接,则应使用UpdateEntryAsync,因为LinkEntryAsync会为单个链接执行此操作。所以要么使用:
var user = await client.For<User>("ApiUser").Key(1).FindEntryAsync();
user.Genres = genres;
await client.For<User>("ApiUser").Key(user).Set(user).UpdateEntryAsync();
或
foreach (var genre in genres)
{
await client.For<User>("ApiUser").Key(user).LinkEntryAsync(genre);
}
可以用更有效的方式编写第一个操作:
await client.For<User>("ApiUser").Key(1).Set(new {Genres = genres}).UpdateEntryAsync();
这将生成HTTP PATCH而不是仅更新Genres的PUT,但看起来您的OData服务要求在正在更新的实体上发送所有必需属性,因此这不起作用。
最后但并非最不重要:获取Simple.OData.Client的最新版本(4.9.1)。它有一个对您的场景很重要的修复。
更新。我测试了你的OData服务,它似乎没有对寻址链接的适当支持。例如,如果我测试样本OData服务,我可以执行http://services.odata.org/V4/OData/%28S%28ygi3rwu514y0a4ooybn3d1gc%29%29/OData.svc/Products%284002%29/Categories/ $ ref之类的请求(注意$ ref段,它解决了Caterogories链接,因此这个URI可用于发布链接更新)。但是,如果我执行请求http:// {your_service_uri} / ApiUsers%281%29 / Genres / $ ref,那么我收到一条错误消息“找不到与请求URI匹配的HTTP资源'http://partymag.azurewebsites.net/ApiUsers(1)/Genres/ $ ref'。”只要此链接在服务器端不起作用,您将无法使用LinkEntryAsync或UnlinkEntryAsync,但您仍然可以使用上面显示的UpdateEntryAsync。
UPDATE2。使用UpdateEntryAsync的版本执行正常,但服务不更新链接,这是Fiddler的结果:
生成的URI:PATCH http:// {your_service_uri} / ApiUsers(1) PATCH有效载荷:
{ "@odata.type":"#PMWeb.Models.Models.User",
"id":1,"Name":"Ege",
"LastName":"Aydin",
"Email":"{removed}",
"Password":"{removed}",
"Genres@odata.bind":[
"http://{your_service_uri}/Genre(31)","http://{your_service_uri}/Genre(32)"
]
}
响应:
{
"@odata.context":"http://{your_service_uri}/$metadata#ApiUsers/$entity",
"id":1,
"Name":"Ege",
"LastName":"Aydin",
"Email":"{removed}",
"Password":"{removed}"
}
如果我现在检查用户类型的内容,它们是相同的。由于生成的有效负载是正确的并且服务接受了它,因此它必须是服务器上未正确执行的东西。