【发布时间】:2016-01-30 20:31:47
【问题描述】:
我正在开发一个 asp.net 网站项目。它没有非常一致的数据层,所以我正在尝试实现代码优先的实体框架。
我最近发现制作实体框架的人已经创建了一个新版本的 EntityDataSource,它可以与 Entity Framework 6 一起使用。
这个新数据源看起来非常好,它会更新数据库。它似乎没有调用我的 DbContext 类上的任何方法。
作为一些基本更改跟踪要求的一部分,我重写了 DbContext SaveChanges() 方法并放入了一些代码来更新每条记录上的跟踪字段(CreatedBy、CreatedDate、ModifiedBy、ModifiedDate)。奇怪的是,当我直接使用 DBContect 时,会调用 SaveChanges() 方法。但是当我使用这个 EntityDataSource 时,它不会调用 SaveChanges()。
上面的实体框架 EntityDataSource 如何更新 dbset?
有什么方法可以让这个 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()。它甚至不调用申请人属性中的 getter 来访问申请人的 DBSet。它仍然设法以某种方式保存信息!
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
【问题讨论】:
-
我没有看到你的 MyDbContext 继承自 DbContext,我认为这是必不可少的。
-
这在我的代码中,它并没有以某种方式进入问题文本。我刚刚更新了这个问题。当我粘贴示例时,我一定是过度简化了!
-
能否包含调用 DbContext 的(示例)代码?我正在寻找您如何执行更新或创建(取决于这两个(或两者)中的哪一个失败)。
-
我通过链接 aspx 页面中的不同控件以声明方式进行更新。有一个 ListView 或 GridView 控制 EntityDataSource。代码隐藏页面中没有代码。当绑定控件上的更新命令被命中时,它只是将它传递给实体数据源的任何内容传递给它,就像魔术一样,它使用 DBContext 并更新数据库。
标签: asp.net .net vb.net entity-framework