自定义Domain Service时遇到实体不能更新的问题及其解决方案
2011-07-19 19:56
489 查看
这是在项目中的一个小问题。我们用到了自定义的Domain Service和自定义Entity,如果仅仅是读取数据,没有任何问题。但如果需要通过双向绑定,实现更新,则可能会遇到一个错误。类似下面这样
本文将重现这个问题,并分析原因和提供解决方案。
【备注】Domain Service看起来很不错,尤其是结合LINQ to Entity的话。但在使用自定义Domain Service时会遇到各种各样的问题,很多问题是让人莫名其妙的。我个人觉得这个设计模型还需要进一步完善的
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
读取数据是没有问题的,但是如果我们去编辑FirstName或者LastName,就会发生如下的错误
这个错误确实让人看得云里雾里的。不是吗?你绝不会想到是要像下面这样解决
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
当然,也可以不叫UpdateEmployee的名字,但参数必须必须是Employee类型
例如下面这样
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
我们可以打开客户端自动生成的那个文件来看一下,里面有一段代码很特殊
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
是在这里,在这个内部密封的类型里面,它设置了Employee这个EntitySet是可以编辑的,而其实这个EntitySetOperation是一个枚举,具有下面可用的值
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
然后自动生成的Domain Service里面就自动具有了Update,Delete,Insert之类的方法,这样就允许这些业务实体支持更新了。
本文将重现这个问题,并分析原因和提供解决方案。
【备注】Domain Service看起来很不错,尤其是结合LINQ to Entity的话。但在使用自定义Domain Service时会遇到各种各样的问题,很多问题是让人莫名其妙的。我个人觉得这个设计模型还需要进一步完善的
1. 自定义业务实体
下面这个类型会被用到服务中返回文件类型映射的信息using System.ComponentModel.DataAnnotations; namespace SilverlightApplication3.Web { public class Employee { [Key] public int ID { get; set; } [Editable(true)] public string FirstName { get; set; } [Editable(true)] public string LastName { get; set; } } }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
2. 自定义Domain Service
namespace SilverlightApplication3.Web { using System.Linq; using System.ServiceModel.DomainServices.Hosting; using System.ServiceModel.DomainServices.Server; // TODO: Create methods containing your application logic. [EnableClientAccess()] public class SampleDomainService : DomainService { public IQueryable<Employee> GetEmployees() { return new[]{ new Employee(){ID=1,FirstName="ares",LastName="chen"}, new Employee(){ID=2,FirstName="bill",LastName="gate"}}.AsQueryable(); } } }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
3. 客户端的ViewModel
using System.Collections.ObjectModel; using Microsoft.Practices.Prism.ViewModel; using SilverlightApplication3.Web; using System.ComponentModel; namespace SilverlightApplication3.ViewModels { public class MainPageViewModel:NotificationObject { public MainPageViewModel() { if(DesignerProperties.IsInDesignTool) return; var ctx = new SampleDomainContext(); ctx.Load<Employee>(ctx.GetEmployeesQuery(), (op) => { Employees = new ObservableCollection<Employee>(op.Entities); }, true); } private ObservableCollection<Employee> _Employees; public ObservableCollection<Employee> Employees { get { return _Employees; } set { if(_Employees != value) { _Employees = value; RaisePropertyChanged("Employees"); } } } } }
4. 页面定义
<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="SilverlightApplication3.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400" xmlns:vm="clr-namespace:SilverlightApplication3.ViewModels"> <UserControl.DataContext> <vm:MainPageViewModel></vm:MainPageViewModel> </UserControl.DataContext> <Grid x:Name="LayoutRoot" Background="White" Margin="20"> <StackPanel> <TextBlock Text="Employee List" FontSize="20"></TextBlock> <sdk:DataGrid Margin="10" ItemsSource="{Binding Employees}" AutoGenerateColumns="False"> <sdk:DataGrid.Columns> <sdk:DataGridTextColumn Binding="{Binding ID}" Header="ID"></sdk:DataGridTextColumn> <sdk:DataGridTextColumn Binding="{Binding FirstName,Mode=TwoWay}" Header="FirstName"></sdk:DataGridTextColumn> <sdk:DataGridTextColumn Binding="{Binding LastName,Mode=TwoWay}" Header="LastName"></sdk:DataGridTextColumn> </sdk:DataGrid.Columns> </sdk:DataGrid> </StackPanel> </Grid> </UserControl>
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
5. 测试运行
读取数据是没有问题的,但是如果我们去编辑FirstName或者LastName,就会发生如下的错误
这个错误确实让人看得云里雾里的。不是吗?你绝不会想到是要像下面这样解决
6. 添加一个Updatexxxx方法,使得Employee这个EntitySet可以被编辑
解决方案居然是要为Employee这个类型,添加一个特殊的方法,用Update做为前缀。看下面的例子namespace SilverlightApplication3.Web { using System.Linq; using System.ServiceModel.DomainServices.Hosting; using System.ServiceModel.DomainServices.Server; // TODO: Create methods containing your application logic. [EnableClientAccess()] public class SampleDomainService : DomainService { public IQueryable<Employee> GetEmployees() { return new[]{ new Employee(){ID=1,FirstName="ares",LastName="chen"}, new Employee(){ID=2,FirstName="bill",LastName="gate"}}.AsQueryable(); } /// <summary> /// 这个方法用来更新员工 /// </summary> /// <param name="e"></param> public void UpdateEmployee(Employee e) { } } }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
当然,也可以不叫UpdateEmployee的名字,但参数必须必须是Employee类型
例如下面这样
namespace SilverlightApplication3.Web { using System.Linq; using System.ServiceModel.DomainServices.Hosting; using System.ServiceModel.DomainServices.Server; // TODO: Create methods containing your application logic. [EnableClientAccess()] public class SampleDomainService : DomainService { public IQueryable<Employee> GetEmployees() { return new[]{ new Employee(){ID=1,FirstName="ares",LastName="chen"}, new Employee(){ID=2,FirstName="bill",LastName="gate"}}.AsQueryable(); } /// <summary> /// 这个方法用来更新员工 /// </summary> /// <param name="e"></param> [Update] public void ModifyEmployee(Employee e) { } } }
7.再次运行测试(客户端代码无需任何修改)
请注意,第一行的FirstName已经被修改了(由ares改成了mike).csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
8. 分析问题的根源
那么,到底发生了什么呢?为什么添加了那个方法就又可以编辑了呢我们可以打开客户端自动生成的那个文件来看一下,里面有一段代码很特殊
internal sealed class SampleDomainContextEntityContainer : EntityContainer { public SampleDomainContextEntityContainer() { this.CreateEntitySet<Employee>(EntitySetOperations.Edit); } }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
是在这里,在这个内部密封的类型里面,它设置了Employee这个EntitySet是可以编辑的,而其实这个EntitySetOperation是一个枚举,具有下面可用的值
#region Assembly System.ServiceModel.DomainServices.Client.dll, v2.0.50727 // C:\Program Files (x86)\Microsoft SDKs\RIA Services\v1.0\Libraries\Silverlight\System.ServiceModel.DomainServices.Client.dll #endregion using System; namespace System.ServiceModel.DomainServices.Client { // Summary: // Enumeration of the types of operations permissable on an System.ServiceModel.DomainServices.Client.EntitySet. [Flags] public enum EntitySetOperations { // Summary: // Only read operations are permitted, no update operations are allowed. None = 0, // // Summary: // New entities may be added Add = 1, // // Summary: // Entities may be updated Edit = 2, // // Summary: // Entities may be removed Remove = 4, // // Summary: // Entities may be added, updated and removed All = 7, } }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
9.题外话:
我们在使用LINQ to Entity作为Domain Service的数据模型的时候,可能就意识不到这个问题,是因为我们可以在创建Domain Service的时候设置是否允许编辑然后自动生成的Domain Service里面就自动具有了Update,Delete,Insert之类的方法,这样就允许这些业务实体支持更新了。
相关文章推荐
- 注意Hibernate4在开发当中的一些改变和遇到的一些问题及其解决方案
- 在百度地图API中使用getOverlays方法遇到的问题及其解决方案
- Ubuntu下Matlab路径不能永久保存的问题及其解决方案
- 将神州4号开发板源代码烧写到开发板上时遇到的问题及其解决方案
- Xcode(各版本)遇到的问题及其解决方案
- 集群新环境遇到表权限问题不能读表解决方案
- Android电视开发问题收集——在实际开发中遇到的问题及其解决方案
- 更新SDK manager后遇到的问题及解决方案
- 使用ef6创建oracle数据库的实体模型遇到的问题及解决方案
- java web开发中遇到的问题及解决方案(个人学习日志,持续更新)
- 平时遇到的问题及其解决方案
- Linux设置静态ip后遇到的问题及其解决方案
- 关于Entity Framework更新的几种方式以及可能遇到的问题(附加类型“Model”的实体失败,因为相同类型的其他实体已具有相同的主键值)在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值,则可能会发生上述行为
- 数据库开发遇到的问题及解决方案(个人日志、持续更新)
- Ubuntu不能利用ssh进行远程连接的解决方案及其解决过程中出现的问题
- 使用VS2010时遇到的一些小问题的解决方案(从各处搜罗总结的,不定期更新,向原作者致敬)
- android 开发中遇到的错误及解决方式(更新R.java文件不能自动更新问题)
- C++学习中遇到的问题及其解决方案
- 遇到了IE10不能登录的问题,很早就有解决方案了
- GridView删除,更新后不能立刻刷新的问题解决方案