我在EF6 DbContext中有一个重写的SaveChanges,我在其中设置了一些日期和用户。这些更改正在保存到数据库中,但我必须退出并重新打开我的WPF表单,然后才能在那里看到。
SaveChanges覆盖是:
//make sure we get all the changed objects
ChangeTracker.DetectChanges();
ObjectContext ctx = ((IObjectContextAdapter) this).ObjectContext;
//get the current user name...
//TODO needs checking that this works when via service.
string userID = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
userID = userID.Substring(userID.IndexOf('\\') + 1); //remove domain
foreach (var dbEntityEntry in ctx.ObjectStateManager
.GetObjectStateEntries(EntityState.Added | EntityState.Modified)
.Where(e => e.Entity is IAuditInfo))
{
switch (dbEntityEntry.State)
{
case EntityState.Added:
((IAuditInfo) dbEntityEntry.Entity).CreatedOn = DateTime.Now;
((IAuditInfo) dbEntityEntry.Entity).CreatedBy = userID;
break;
case EntityState.Modified:
((IAuditInfo) dbEntityEntry.Entity).LastUpdatedOn = DateTime.Now;
((IAuditInfo) dbEntityEntry.Entity).LastUpdatedBy = userID;
break;
case EntityState.Deleted:
case EntityState.Detached:
case EntityState.Unchanged:
default:
break;
}
}
ctx.SaveChanges(SaveOptions.None);
return base.SaveChanges();
我的WPF XAML:
<Page.Resources>
<CollectionViewSource x:Key="actionStatusesViewSource"
d:DesignSource="{d:DesignInstance my:ActionStatus, CreateList=True}" />
</Page.Resources>
<Grid DataContext="{StaticResource actionStatusesViewSource}"
Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<DataGrid Grid.Row ="1"
AutoGenerateColumns="False"
EnableRowVirtualization="True"
ItemsSource="{Binding}"
Name="actionStatusesDataGrid"
RowDetailsVisibilityMode="VisibleWhenSelected"
VerticalAlignment="Top"
ClipboardCopyMode="IncludeHeader">
<DataGrid.Columns>
<DataGridTextColumn x:Name="idColumn"
Binding="{Binding Path=Id, Mode=TwoWay}"
Header="Id"
Width="SizeToHeader" />
<DataGridTextColumn x:Name="nameColumn"
Binding="{Binding Path=Name, Mode=TwoWay}"
Header="Name"
Width="256" />
<DataGridTemplateColumn x:Name="validFromColumn"
Header="Valid From"
Width="128">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding Path=ValidFrom, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn x:Name="validToColumn"
Header="Valid To"
Width="128">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding Path=ValidTo, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn x:Name="lastUpdatedByColumn"
Binding="{Binding Path=LastUpdatedBy, Mode=TwoWay}"
Header="Updated By"
Width="SizeToHeader" />
<DataGridTextColumn x:Name="lastUpdatedOnColumn"
Binding="{Binding Path=LastUpdatedOn, Mode=TwoWay, StringFormat=\{0:dd/MM/yyyy HH:mm\}}"
Header="Updated On"
Width="SizeToCells" />
<DataGridTextColumn x:Name="createdByColumn"
Binding="{Binding Path=CreatedBy, Mode=TwoWay}"
Header="Created By"
Width="SizeToHeader" />
<DataGridTextColumn x:Name="createdOnColumn"
Binding="{Binding Path=CreatedOn, Mode=TwoWay, StringFormat=\{0:dd/MM/yyyy HH:mm\}}"
Header="Created On"
Width="SizeToCells" />
</DataGrid.Columns>
</DataGrid>
最后我加载并保存代码:
private RegRiskContext context; //our model context (via the service)
private DataServiceCollection<ActionStatus> actionStatusBinding; //our bound collection
private CollectionViewSource viewSource; //the view source for the collection
private delegate void OperationResultCallback(); //delegate for the dispatcher invokes
public AdminActionStatus()
{
InitializeComponent();
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
//get the CollectionViewSource object
viewSource = ((CollectionViewSource) (this.FindResource("actionStatusesViewSource")));
try
{
UIHelper.ProgressBarRun(true);
//initialise the context
context = new RegRiskContext(new Uri(RegRiskSettings.Default.ServiceURL));
//create a query ready for the async operation
DataServiceQuery<ActionStatus> dsq = context.ActionStatuses;
try
{
dsq.BeginExecute(OnQueryCompleted, dsq);
}
catch (DataServiceClientException ex)
{
MessageBox.Show(ex.ToString());
}
/* synchronous version
* note the freeze when opening the window
var q = context.ActionStatuses.OrderBy(f => f.Id);
DataServiceCollection<ActionStatus> actionStatuses = new DataServiceCollection<ActionStatus>(q);
viewSource.Source = actionStatuses;
*/
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void OnQueryCompleted(IAsyncResult result)
{
// Get the original query object from the state cache.
DataServiceQuery<ActionStatus> query = (DataServiceQuery<ActionStatus>) result.AsyncState;
//use Dispatcher to ensure we're on the UI thread!
this.Dispatcher.BeginInvoke(new OperationResultCallback(delegate
{
try
{
//instantiate the binding collection using results of the query
actionStatusBinding = new DataServiceCollection<ActionStatus>(query.EndExecute(result));
//set the Source to the collection
viewSource.Source = actionStatusBinding;
UIHelper.ProgressBarRun(false);
}
catch (DataServiceRequestException ex)
{
MessageBox.Show(ex.ToString());
}
}), null);
}
private void saveButton_Click(object sender, RoutedEventArgs e)
{
try
{
UIHelper.ProgressBarRun(true);
context.BeginSaveChanges(OnSaveChangesCompleted, null);
}
catch (DataServiceClientException ex)
{
MessageBox.Show(ex.ToString());
}
}
private void OnSaveChangesCompleted(IAsyncResult result)
{
// Use the Dispatcher to ensure that the operation returns in the UI thread.
this.Dispatcher.BeginInvoke(new OperationResultCallback(delegate
{
try
{
// Complete the save changes operation.
context.EndSaveChanges(result);
viewSource.View.Refresh();
UIHelper.ProgressBarRun(false);
}
catch (DataServiceRequestException ex)
{
MessageBox.Show(ex.ToString());
}
}), null);
}
我不知道是否因为我的SaveChanges覆盖需要以某种方式通知?或者如果它的WPF错了? 在WPF和EF之间有一个WCF DataServices层,但看起来很简单&#39;够了,我无法看到我甚至可以改变它。
答案 0 :(得分:0)
找到了一个解决方案,但并不完全确定为什么它会修复它,所以任何扩展的解释都会感激不尽。
我的WCF DataService类很简单:
public class RegRiskService : EntityFrameworkDataService<BOI.RegRisk.Model.RegRiskContext>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
//snip access stuff
}
}
这是协议版本,默认为v2,将其更改为v3似乎已经解决了问题。我的WPF数据网格现在使用SaveChanges覆盖中所做的更改进行了更新。
对于任何有同样原始问题的人来说,还有一个警告,我一直在看这个问题,所以有可能我改变了其他的东西,这是真正的根本原因!