实体框架6 EntityDataSource在DbContext中未调用SaveChanges

埃瓦尔·基涅瓦尔

我正在asp.net网站项目中开发。它没有非常一致的数据层,因此我正在尝试实现代码优先实体框架。

我最近发现,制作实体框架的人们已经创建了与Entity Framework 6一起使用的EntityDataSource新版本。

http://blogs.msdn.com/b/webdev/archive/2014/02/28/announcing-the-release-of-dynamic-data-provider-and-entitydatasource-control-for-entity-framework-6。 aspx

这个新的数据源看起来确实不错,并且可以更新数据库。它似乎没有调用我的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如何去更新数据库集?

EntityDataSource使用基础ObjectContext而不是DbContext。这就是为什么您永远不会看到任何直接通过SaveChanges()DbContext重载的事情的原因。

有什么方法可以使这个EntityDataSource调用DbContext SaveChanges()方法?

是的,不是,您可以重载该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();
    }

是否有替代DBContext SaveChanges方法的替代方法?

只有我上面描述的。您可以挂钩ObjectContext尽管事件并传递事件,但是在创建上下文时需要它的一个实例(请参见该事件)。然后,您可以将SavingChanges事件订阅为您的钩子,尽管它比SaveChangesDbContext受到更多限制如果你想做的就是

这是可以连接的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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

未调用种子方法,实体框架6

来自分类Dev

实体框架6中未更改的对象

来自分类Dev

是否可以在调用DbContext.SaveChanges之前查询实体框架?

来自分类Dev

在实体框架6中对ICollection进行排序

来自分类Dev

实体框架6中的Alter Database

来自分类常见问题

实体框架6中的多异步?

来自分类Dev

实体框架6中的基类?

来自分类Dev

实体框架6中的MergeOption在哪里?

来自分类Dev

实体框架6中的CreatedOn列

来自分类Dev

实体框架6中类型之间的转换

来自分类Dev

在实体框架6中使用TransactionScope

来自分类Dev

实体框架6中的连接池

来自分类Dev

实体框架6中的MergeOption在哪里?

来自分类Dev

实体框架6中的参数化架构

来自分类Dev

实体框架6中的复杂子查询

来自分类Dev

在实体框架6中保存分离的实体

来自分类Dev

在实体框架6中保存分离的实体

来自分类Dev

在实体框架6中删除子实体时出错

来自分类Dev

实体框架6 SaveChanges导致唯一约束异常

来自分类Dev

实体框架6上下文未检索导航属性

来自分类Dev

实体框架6 MySQL-属性未正确插入

来自分类Dev

实体框架6未创建数据库

来自分类Dev

实体框架6-如何在调用SaveChanges之前查看将为插入生成的SQL

来自分类Dev

使用实体框架6调用数据库函数

来自分类Dev

实体框架6-调用从数据库中删除实体的方法

来自分类Dev

实体框架6中的文件和文件组

来自分类Dev

实体框架6在代码中设置连接字符串

来自分类Dev

实体框架6-无法更新表中的单个列

来自分类Dev

实体框架6中的更新而无需往返