当我保存发票
时,我有这些课程string serviceUri = "http://myserviceurl.azurewebsites.net/odata/";
var container = new Default.Container(new Uri(serviceUri));
var myInvoice = container.Invoice.Expand("CreatedBy").Where(x => x.Id == new Guid("B7E5EEAD-EA77-4174-8305-50440AD057C7")).Skip(0).First();
myInvoice.CreatedBy = container.User.First();
container.UpdateObject(myInvoice);
它保存了Invoice(字段:GUID,字符串),但是 CreatedBy 用户字段没有保存(它没有发送到服务器,在服务器端我检查了它并且空)
如何修复它,或者它是ODATA 4中的限制?
我应该只将ODATA用于读取; 并创建另一个WebApi来保存整个发票实体(包括CreatedBy)?评论,解决方案将不胜感激。
[PropertyChanged.ImplementPropertyChanged]
public class User
{
[Index]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public string Name { get; set; }
}
[PropertyChanged.ImplementPropertyChanged]
public class Invoice
{
[Index]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public User CreatedBy { get; set; } // how to save this?
[InverseProperty("Invoice")]
public ICollection<InvoiceItem> Items { get; set; } // how to save this?
}
[PropertyChanged.ImplementPropertyChanged]
public class InvoiceItem
{
[Index]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public Invoice Invoice { get; set; }
public decimal Qty { get; set; }
public decimal Price { get; set; }
public decimal Total { get; set; }
}
在这些情况下,ODATA是否仅适用于READ?要写,我应该写自己的WebApi? 这样的事情:(或者可能是这个的通用版本)
public void Post([FromBody] Invoice p)
{
SyncContext db = new SyncContext();
db.Entry(p).State = System.Data.Entity.EntityState.Modified; // Exists?
foreach (var item in p.Items)
{
var f = db.InvoiceItem.Where(i => i.Id == item.Id).FirstOrDefault();
db.Entry(item).State = f == null ?
System.Data.Entity.EntityState.Added :
System.Data.Entity.EntityState.Modified;
}
db.SaveChanges();
}
客户方:
using (var client = new WebClient())
{
var dataString = JsonConvert.SerializeObject(myInvoice);
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
client.UploadString(new Uri("http://localhost:56948/odata/Invoice"), "POST", dataString);
}
答案 0 :(得分:1)
您需要将用户添加为发票的外键。由于您的用户ID是由数据库创建的,因此您需要先创建用户。
public class Invoice
{
...
// New code:
[ForeignKey("User")]
public Guid userId { get; set; }
public virtual User User { get; set; }
}
答案 1 :(得分:0)
经过几天调查这个问题,并尝试使用一些库,在ODATA 3,ODATA 4,甚至MongoDB和DocumentDB上, 我可以说这个问题是由系统进入和存储数据的深度问题引起的。根据保存的对象,可以通过发票上的简单保存来访问几乎整个数据库。
我认为可以做的是在 CreatedBy 中实现 [NotRecursive] 这样的注释,
因此它只会发送该属性的密钥,而不是整个 CreatedBy(用户)图。
另一种可能的数据注释是 [RecursiveLevel(NumberOfLevels)]
这个递归问题会影响它们:Entity,NHibernate,ODATA,甚至像MongoDB和DocumentDB这样的Document存储。
需要创建一个简单的规范(Data Annotation)来解决这个嵌套级别定义,以便在各种数据库和ORM / Mapper上进行保存。