简体   繁体   English

更新Azure表存储中的断开连接的实体

[英]Updating Disconnected Entity in Azure Table Storage

I am working a sample application using Windows Azure table storage. 我正在使用Windows Azure表存储来处理示例应用程序。 I will try to explain it using some code: 我将尝试使用一些代码来解释它:

//GetStudent is a service call
StudentDetails student = this.GetStudent(studentID);

This code returns me a StudentDetails object with both PartitionKey and RowKey as null since both of those are not DataMembers in my DataContract. 这段代码返回的StudentDetails对象的PartitionKey和RowKey为null,因为这两个都不是我的DataContract中的DataMembers。

//Update the student object
student.LastName = "New Last Name";
this.UpdateStudent(student);//Another service call

My update service code looks like below: 我的更新服务代码如下所示:

context.AttachTo(StudentDataServiceContext.studentTableName, student, "*");
context.UpdateObject(student);
context.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate);

When I run this code I get the below error: 当我运行此代码时,出现以下错误:

One of the request input is not valid

I did find a workaround to solve this and updated the UpdateService code like below: 我确实找到了解决此问题的解决方法,并更新了UpdateService代码,如下所示:

StudentDetails temp = (from c in context.StudentTable
                       where c.PartitionKey == "Student" && c.RowKey == student.ID
                       select c).FirstOrDefault();
//Copy each and every property from student object to temp object
temp.LastName = student.LastName;
context.UpdateObject(temp);
context.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate);

This works fine and the object gets updated in the table storage. 这可以正常工作,并且对象在表存储中得到更新。

But is there not a better way of doing this? 但是,没有更好的方法吗? Why doesn't the AttachTo function work in my case? 为什么在我的情况下AttachTo函数不起作用?

EDIT 编辑

Just to make my question more clear, here is my StudentDetails Class: 为了使我的问题更清楚,这是我的StudentDetails类:

[DataContract]
public class StudentDetails
{
        public string PartitionKey { get; set; }
        public string RowKey { get; set; }

        [DataMember]
        public string First Name { get; set; }

        [DataMember]
        public string Last Name { get; set; }

        [DataMember]
        public string ID { get; set; }
}

And below is my GetStudent method: 下面是我的GetStudent方法:

BasicHttpBinding myBinding = new BasicHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress(RoleEnvironment.GetConfigurationSettingValue("StudentServiceURI"));
ChannelFactory<IPatientService> myChannelFactory = new ChannelFactory<IStudentService>(myBinding, myEndpoint);
IStudentService proxy = myChannelFactory.CreateChannel();
student = proxy.GetPatient(studentID);
((IClientChannel)proxy).Close();
myChannelFactory.Close();

I feel the problem is with my GetStudent's channel factory call which is missing something related to service's context. 我觉得问题出在我的GetStudent的频道工厂调用中,该调用缺少与服务上下文有关的内容。 I just don't know what. 我就是不知道

You said that the Student object returned doesn't have a PartitionKey and RowKey set when it is returned. 您说返回的Student对象在返回时没有设置PartitionKeyRowKey You then try to update that object. 然后,您尝试更新该对象。 If you haven't set the PartitionKey and RowKey yourself before calling .Update() this will fail as the underlying REST API depends on these. 如果尚未在调用.Update()之前自行设置PartitionKeyRowKey此操作将失败,因为基础REST API依赖于这些。

It occurs when testing the application with empty tables in development storage. 在开发存储中使用空表测试应用程序时会发生这种情况。 This is because Development Storage currently requires the schema for an entity stored in a table to have been previously defined before you are allowed to query it. 这是因为Development Storage当前需要在允许您查询之前已预先定义表中存储的实体的架构。

Workaround 解决方法

The workaround is simple, we just need to insert, and then delete, a dummy row into the Windows Azure tables if the application is running in the development fabric. 解决方法很简单,如果应用程序在开发结构中运行,我们只需要在Windows Azure表中插入然后删除一个虚拟行即可。 During the initialization of the web role, it is a good idea if the application checks whether it is running against local development storage, and if this is the case, it adds, and then deletes, a dummy record to the application's Windows Azure tables (It will be done just the first time, per Entity, when working against the Development Storage). 在初始化Web角色期间,如果应用程序检查它是否针对本地开发存储运行,则是一个好主意;如果是这种情况,它会在应用程序的Windows Azure表中添加(然后删除)虚拟记录(在对开发存储进行操作时,这仅是每个实体的第一次。

That code can be added using an extension method, for instance. 例如,可以使用扩展方法添加该代码。

More info on: 有关更多信息:

http://msdn.microsoft.com/en-us/library/ff803365.aspx http://msdn.microsoft.com/en-us/library/ff803365.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM