更新 Azure 表存储中断开连接的实体
我正在使用 Windows Azure 表存储开发一个示例应用程序。我将尝试使用一些代码来解释它:
//GetStudent is a service call
StudentDetails student = this.GetStudent(studentID);
此代码返回一个 StudentDetails 对象,其中 PartitionKey 和 RowKey 都为 null,因为它们都不是我的 DataContract 中的 DataMember。
//Update the student object
student.LastName = "New Last Name";
this.UpdateStudent(student);//Another service call
我的更新服务代码如下所示:
context.AttachTo(StudentDataServiceContext.studentTableName, student, "*");
context.UpdateObject(student);
context.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate);
当我运行此代码时,出现以下错误:
One of the request input is not valid
我确实找到了解决此问题的解决方法并更新了 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);
这工作正常,并且对象在表存储中更新。
但是没有更好的方法吗?为什么 AttachTo 函数在我的情况下不起作用?
编辑
只是为了让我的问题更清楚,这是我的 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; }
}
下面是我的 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();
我觉得问题出在我的 GetStudent 通道工厂调用上,它缺少与服务上下文相关的内容。我只是不知道是什么。
I am working a sample application using Windows Azure table storage. 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.
//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:
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?
EDIT
Just to make my question more clear, here is my StudentDetails Class:
[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:
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. I just don't know what.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您说返回的
Student
对象在返回时没有设置PartitionKey
和RowKey
。然后您尝试更新该对象。如果您在调用.Update()
之前没有自行设置PartitionKey
和RowKey
,则此操作将会失败,因为底层 REST API 依赖于这些。You said that the
Student
object returned doesn't have aPartitionKey
andRowKey
set when it is returned. You then try to update that object. If you haven't set thePartitionKey
andRowKey
yourself before calling.Update()
this will fail as the underlying REST API depends on these.当使用开发存储中的空表测试应用程序时会发生这种情况。这是因为开发存储当前需要先定义存储在表中的实体的架构,然后才能查询它。
解决方法
解决方法很简单,如果应用程序在开发结构中运行,我们只需将虚拟行插入到 Windows Azure 表中,然后删除。在 Web 角色初始化期间,应用程序最好检查它是否正在针对本地开发存储运行,如果是这种情况,它会向应用程序的 Windows Azure 表添加一条虚拟记录,然后删除该记录(当针对开发存储工作时,每个实体都会第一次完成此操作)。
例如,可以使用扩展方法添加该代码。
详细信息:
http://msdn.microsoft.com/en-us/library /ff803365.aspx
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.
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. 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).
That code can be added using an extension method, for instance.
More info on:
http://msdn.microsoft.com/en-us/library/ff803365.aspx