Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 更新Azure表存储中断开连接的实体_C#_Azure_Azure Storage_Azure Table Storage - Fatal编程技术网

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

C# 更新Azure表存储中断开连接的实体,c#,azure,azure-storage,azure-table-storage,C#,Azure,Azure Storage,Azure Table Storage,我正在使用WindowsAzure表存储开发一个示例应用程序。我将尝试使用一些代码来解释它: //GetStudent is a service call StudentDetails student = this.GetStudent(studentID); 这段代码返回一个StudentDetails对象,其中PartitionKey和RowKey都为null,因为它们在我的DataContract中都不是DataMember //Update the student object stu

我正在使用WindowsAzure表存储开发一个示例应用程序。我将尝试使用一些代码来解释它:

//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);
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);
当我运行此代码时,会出现以下错误:

One of the request input is not valid
我确实找到了解决此问题的方法,并更新了UpdateService代码,如下所示:

context.AttachTo(StudentDataServiceContext.studentTableName, student, "*");
context.UpdateObject(student);
context.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate);
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();
BasicHttpBinding myBinding=new BasicHttpBinding();
EndpointAddress myEndpoint=新的EndpointAddress(RoleEnvironment.GetConfigurationSettingValue(“StudentServiceURI”);
ChannelFactory myChannelFactory=新的ChannelFactory(myBinding,myEndpoint);
IStudentService proxy=myChannelFactory.CreateChannel();
student=proxy.GetPatient(studentID);
((IClientChannel)代理).Close();
myChannelFactory.Close();

我觉得问题在于GetStudent的channel factory调用缺少与服务上下文相关的内容。我只是不知道是什么。

在开发存储中使用空表测试应用程序时会发生这种情况。这是因为开发存储当前要求存储在表中的实体的模式在允许您查询之前已被预先定义

变通办法

解决方法很简单,如果应用程序在开发结构中运行,我们只需要在WindowsAzure表中插入然后删除一个虚拟行。在web角色的初始化过程中,如果应用程序检查它是否在本地开发存储上运行,并且如果是这样,它会在应用程序的Windows Azure表中添加,然后删除一条虚拟记录,这是一个好主意(在使用开发存储时,每个实体只会第一次这样做)

例如,可以使用扩展方法添加该代码

更多有关:


您说过,返回的
Student
对象在返回时没有设置
PartitionKey
RowKey
。然后尝试更新该对象。如果在调用
.Update()
之前没有自己设置
分区键
行键
,这将失败,因为底层REST API依赖于这些记录。

我的表中已有大约5条记录,我的select查询工作正常。我只在选择然后从客户端更新时收到错误。为什么GetStudent方法返回一个分区和行键为空的实体?这就是更新失败的原因。服务无法使用密钥的空值更新记录。任何服务都不会。在设计自己的实体时,您应该继承TableServiceEntity类,以确保一切正常工作!GetStudent是一个内部使用WCF服务调用的用户。我的实体(StudentDetails)不将RowKey和PartitionKey公开为DataMembers,因此当服务返回时,它将只返回标记为DataMember的属性。我知道问题在于空PartitionKey和RowKey。它们为null,因为它们未声明为DataMembers。问题在于通过服务调用维护TableServiceContext。因为我正在使用Channel Factory进行服务调用,所以我想我需要编写一些与TableServiceContext相关的额外代码。但我不知道怎么做。此外,还更新了原始问题以使其更清楚。在这种情况下,您已经知道要解决问题需要做什么,可以将PartitionKey和RowKey作为数据成员包括在内,也可以在保存之前对其进行设置。它与在TableServiceContext中维护的任何内容无关,因为您正在对etag使用带有“*”的
AttachTo
,该代码完全正确。哦,我现在知道了。我在web上看到的大多数示例都建议不要将RowKey和PartitionKey公开为数据成员。这就是我没有揭露他们的原因。谢谢你的解释。将此标记为答案:-)