我正在asp.net网站项目中开发。它没有非常一致的数据层,因此我正在尝试实现代码优先实体框架。
我最近发现,制作实体框架的人们已经创建了与Entity Framework 6一起使用的EntityDataSource新版本。
这个新的数据源看起来确实不错,并且可以更新数据库。它似乎没有调用我的DbContext类上的任何方法。
作为一些基本更改跟踪要求的一部分,我重写了DbContext SaveChanges()方法,并放入了一些代码来更新每个记录(CreatedBy,CreatedDate,ModifiedBy,ModifiedDate)上的跟踪字段。奇怪的是,当我直接使用DBContect时,将调用SaveChanges()方法。但是,当我使用此EntityDataSource时,它不会调用SaveChanges()。
上面的实体框架EntityDataSource如何去更新数据库集?
有什么方法可以使这个EntityDataSource调用DbContext SaveChanges()方法?
是否有替代DBContext SaveChanges方法的替代方法?
这是我的实体框架EntityDataSource控件定义的示例
<asp:ListView ID="FormView" runat="server" DataKeyNames="RecordId" DataSourceID="ApplicantDataSource" DefaultMode="Edit">
<EditItemTemplate>
<asp:TextBox runat="server" ID="SomeField" Text='<%# Bind("SomeField")%>' ></asp:TextBox>
</EditItemTemplate>
</asp:ListView>
<ef:EntityDataSource runat="server"
ID="ApplicantDataSource"
ContextTypeName="Organisation.Application.MyDbContext"
EntitySetName="Applicants"
Where="it.RecordId=@RecordId"
EnableUpdate="true">
<WhereParameters>
<asp:QueryStringParameter Name="RecordId" QueryStringField="RecordId" DbType="String" DefaultValue=""/>
</WhereParameters>
</ef:EntityDataSource>
这是我的DbContext(已删除)。在EntityDataSource上调用update时,它不会通过SaveChanges()传递。它甚至不调用Applicants属性中的getter来访问DBSet of Applicants。它仍然设法以某种方式保存信息!
Public Class MyDbContext
Inherits DbContext
Public Shared Sub MyDbContext()
Database.SetInitializer(Of MyDbContext)(Nothing)
End Sub
Public Sub New()
MyBase.New("Name=ConnectionString")
End Sub
Public Property Applicants() As DbSet(Of Applicant)
Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
modelBuilder.Conventions.Remove(Of PluralizingTableNameConvention)()
MyBase.OnModelCreating(modelBuilder)
End Sub
Public Overrides Function SaveChanges() As Integer
Try
Dim entities = Me.ChangeTracker.Entries().Where(Function(x) TypeOf x.Entity Is MyBase AndAlso (x.State = EntityState.Added OrElse x.State = EntityState.Modified))
Dim currentUsername As String
If HttpContext.Current IsNot Nothing And HttpContext.Current.User IsNot Nothing Then
currentUsername = HttpContext.Current.User.Identity.Name
Else
currentUsername = "System"
End If
For Each entity In entities
If entity.State = EntityState.Added Then
DirectCast(entity.Entity, MyBase).CreatedDate = DateTime.Now
DirectCast(entity.Entity, MyBase).CreatedBy = currentUsername
ElseIf entity.State = EntityState.Modified Then
entity.Property("CreatedBy").IsModified = False
entity.Property("CreatedDate").IsModified = False
End If
DirectCast(entity.Entity, MyBase).ModifiedDate = DateTime.Now
DirectCast(entity.Entity, MyBase).ModifiedBy = currentUsername
Next
Return MyBase.SaveChanges()
Catch ex As DbEntityValidationException
' Retrieve the error messages as a list of strings.
Dim errorMessages = ex.EntityValidationErrors.SelectMany(Function(x) x.ValidationErrors).[Select](Function(x) x.ErrorMessage)
' Join the list to a single string.
Dim fullErrorMessage = String.Join("; ", errorMessages)
' Combine the original exception message with the new one.
Dim exceptionMessage = String.Concat(ex.Message, " The validation errors are: ", fullErrorMessage)
' Throw a new DbEntityValidationException with the improved exception message.
Throw New DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors)
End Try
End Function
End Class
EntityDataSource使用基础ObjectContext而不是DbContext。这就是为什么您永远不会看到任何直接通过SaveChanges()
DbContext重载的事情的原因。
是的,不是,您可以重载该Updating
方法,然后EntityDataSourceChangingEventArgs
可以访问DbContext,然后对其进行调用。不过,这对于您的所有视图都是必需的,我看不出有一种方法可以轻松地将其及其不良设计集中化(因此,没有)。
protected void x_Updating(object sender, EntityDataSourceChangingEventArgs e) {
e.Cancel = true;
DbContext dbc = new DbContext(e.Context, true);
new YourDbContext(dbc).SaveChanges();
}
只有我上面描述的。您可以挂钩ObjectContext
尽管事件并传递事件,但是在创建上下文时需要它的一个实例(请参见该事件)。然后,您可以将SavingChanges事件订阅为您的钩子,尽管它比SaveChanges
DbContext受到更多限制。如果你想做的就是
这是可以连接的Vb.Net代码示例。如果语法不正确,请不要向我开枪,自从我用Vb编写任何东西以来,已经很久了。您可能需要onContextCreated
在设计器中注册(aspx代码)。
免责声明-我尚未测试以下代码。它部分基于您的代码和SavingChanges文档中的示例代码。
Protected Sub onContextCreated(ByVal sender As Object, ByVal args As EntityDataSourceContextCreatedEventArgs)
AddHandler args.Context.SavingChanges, AddressOf context_SavingChanges
End Sub
Private Sub context_SavingChanges(ByVal sender As Object, ByVal e As EventArgs)
Dim context As ObjectContext = TryCast(sender, ObjectContext)
If context IsNot Nothing Then
If HttpContext.Current IsNot Nothing And HttpContext.Current.User IsNot Nothing Then
currentUsername = HttpContext.Current.User.Identity.Name
Else
currentUsername = "System"
End If
For Each entity As ObjectStateEntry In context.ObjectStateManager.GetObjectStateEntries(EntityState.Added Or EntityState.Modified)
If entity.State = EntityState.Added Then
DirectCast(entity.Entity, MyBase).CreatedDate = DateTime.Now
DirectCast(entity.Entity, MyBase).CreatedBy = currentUsername
ElseIf entity.State = EntityState.Modified Then
entity.Property("CreatedBy").IsModified = False
entity.Property("CreatedDate").IsModified = False
End If
DirectCast(entity.Entity, MyBase).ModifiedDate = DateTime.Now
DirectCast(entity.Entity, MyBase).ModifiedBy = currentUsername
Next
End If
End Sub
部分答案的来源:http : //w3stack.org/question/how-can-i-override-dbcontext-savechanges-when-using-entitydatasource-and-database-generated-model-edmx-ef-5/
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句