加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

当用户使用ASP.NET应用程序中的Entity Framework 4和VB.NET更新

发布时间:2020-12-16 09:37:43 所属栏目:asp.Net 来源:网络整理
导读:这是我的第一篇文章,希望我遵守规则! 经过几个星期的撞击砖墙和无休止的互联网搜索,我已经决定自己发帖,并希望找到所有专家的答案和指导. 我正在构建一个ASP.NET应用程序(在Visual Studio 2010中),它使用SQL 2008数据库和实体框架4将这两个部分连接在一起.
这是我的第一篇文章,希望我遵守规则!

经过几个星期的撞击砖墙和无休止的互联网搜索,我已经决定自己发帖,并希望找到所有专家的答案和指导.

我正在构建一个ASP.NET应用程序(在Visual Studio 2010中),它使用SQL 2008数据库和实体框架4将这两个部分连接在一起.我首先将数据库设计为数据库项目,然后将实体模型构建为类项目,然后在主ASP.NET项目中引用.我相信这在实体框架术语中称为数据库优先?

我是Web Apps的新手(我主要开发WinForms应用程序),这是我第一次尝试使用Entity Framwork.

我可以了解C#,因此如果可能的话,您可能会在VB中首选任何代码示例或代码段.

给出一些我到目前为止的背景.我构建了一个名为register.aspx的regsitration页面,并使用ASP创建了一个向导样式表单:ASP:TextBox,ASP:DropdownList和ASP:CheckBoxList它们都在HTML表格中布局,并使用CSS进行一些格式化.一旦用户获得向导中的最后一页并按“完成”,我将在VB代码后面执行一些代码,如下所示:

Protected Sub wizardRegister_FinishButtonClick(sender As Object,e As System.Web.UI.WebControls.WizardNavigationEventArgs) Handles wizardRegister.FinishButtonClick
    Dim context As New CPMModel.CPMEntities
    Dim person As New CPMModel.Person
    Dim employee As New CPMModel.Employee

    Dim newID As Guid = Guid.NewGuid

    With person
        .ID = newID
        .UserID = txbx_UserName.Text
        .Title = ddl_Title.SelectedValue
        .FirstName = txbx_FirstName.Text
        .MiddleInitial = txbx_MiddleInitial.Text
        .FamilyName = txbx_FamilyName.Text
        .Gender = ddl_Gender.SelectedValue
        .DOB = txbx_DOB.Text
        .RegistrationDate = Date.Now
        .RegistrationMethod = "W"
        .ContactMethodID = New Guid(ddl_ContactMethodList.SelectedValue)
        .UserName = txbx_UserName.Text
        If Not (My.Settings.AuthenticationUsingAD) Then
            .Password = txbx_Password.Text ' [todo] write call to salted password hash function
        End If
        .IsRedundant = False
        .IsLocked = False
    End With

    context.AddToPeople(person)

    With employee
        .ID = newID
        .PayrollNumber = txbx_PayrollNumber.Text
        .JobTitle = txbx_JobTitle.Text
        .DepartmentID = ddl_DepartmentList.SelectedValue
        .OfficeNumber = txbx_OfficeNumber.Text
        .HomeNumber = txbx_HomeNumber.Text
        .MobileNumber = txbx_MobileNumber.Text
        .BleepNumber = txbx_BleepNumber.Text
        .OfficeEmail = txbx_OfficeEmail.Text
        .HomeEmail = txbx_HomeEmail.Text
        .IsRedundant = False
        .RedundantDate = Nothing

         '--------------------------
        .FiledBy = Threading.Thread.CurrentPrincipal.Identity.Name
        .FiledLocation = My.Computer.Name
        .FiledDateTimeStamp = Date.Now
        '----------------------------
    End With

    context.AddToEmployees(employee)
    context.SaveChanges()
End Sub

以上工作正常,似乎是一种明智的做法(记住我是实体??框架的新手),并给了我我所期望的结果.

我在这个页面上有另一个名为manage.aspx的页面是一个选项卡控件,每个选项卡页面都包含一个asp:DetailsView,它绑定到一个asp:EntityDataSource,我已经启用了对所有实体数据源的更新以及一些我也启用了插入,没有启用删除.

如果我在此阶段构建并运行应用程序一切正常,您可以按“编辑”链接进行更改,然后按“更新”,确保这些更新立即显示在屏幕上,数据库确实具有正确的值.

这是问题,我需要拦截上面代码中的更新(粗体位)注意我的数据库中有一个名为FiledBy,FiledLocation和FiledDateTimeStamp的列.我不想向查看ASP.NET页面的用户显示这些列,但我想在用户按下更新时更新它们(如果有任何更改).我已经尝试将ASP:DetailsView转换为模板,然后使用类似的东西对HTML进行编码;

<@# Eval(User.Name) #>

我确实设法让它在编辑模式下将正确的值放在文本框中,但我遇到了以下问题;

>它没有保存到数据库
>我必须显示我不想做的文本框

我已经在这里和其他网站上阅读了其他几个帖子,你可以覆盖Entity Framwork模型的SaveChanges部分,其中一个例子就在下面的代码中;

public override int SaveChanges() 
{
var entities = ChangeTracker.Entries<YourEntityType>() 
                            .Where(e => e.State == EntityState.Added) 
                            .Select(e => e.Entity); 
var currentDate = DateTime.Now; 
foreach(var entity in entities) 
{ 
    entity.Date = currentDate; 
} 

return base.SaveChanges(); 
}

问题是,虽然我理解了这个想法,并且可以将它转换为VB,但我不知道如何实现它.我在哪里放代码?我该如何调用代码?等等

我希望找到满足以下要求的解决方案:

>如果我要重新生成/更新实体模型,不会被覆盖
>不需要为我的模型中的每个表复制和粘贴(大多数但不是全部都有审计列)
>可以用于其他列,例如,如果用户在检查列表中进行选择,我可能希望将某个值写入另一个(未公开给用户)列.

我采用正确的方法在可能的网页中显示数据我当然发现DataView和GridView限制,我确实考虑创建一个表格,如表格标签中的注册表单,但没有想法如何使用数据库中的值填充文本框等也不知道如何实现分页,因为许多表都有一对多的关系,尽管如果我在表上填充文本框,保存更改会很容易.

提前感谢所有提供支持的人.

凯文.

好的,所以我现在离得更近了,但仍然没有让它正常工作.我使用以下代码编辑Databound事件的DetailsView中的值.如果将正确的时间戳写入只读文本框,但在按下DetailsView控件上的“更新”按钮时,不会将此值返回到数据库.

Protected Sub dv_Employee_DataBound(sender As Object,e As EventArgs) Handles dv_Employee.DataBound
    If dv_Employee.CurrentMode = DetailsViewMode.Edit Then
        For Each row In dv_Employee.Rows
            If row.Cells(0).Text = "FiledDateTimeStamp" Then
                row.Cells(1).Text = Date.Now()
            End If
        Next
    End If
End Sub

解决方法

我喜欢覆盖保存更改方法的想法.您的上下文应该是一个部分类,因此您只需要在同一名称空间中定义另一个标记为partial的类,并为其添加覆盖.

Namespace CPMModel
  Partial Public Class CPMEntities
   ...Your override here
End Class

由于这是对默认SaveChanges方法的重写,因此您无需对其调用方式进行任何更改.您需要找到一种获取实体级属性的方法.

由于这是为所有实体提交更改的方法,因此您无法像在示例中那样访问属性,因为实体类未定义您的具体属性.因此,您需要为实体创建部分类,并让它们都实现一个定义您想要与之交互的属性的接口.

创建界面:

Interface IDate
   Property Date() as DateTime
End Interface

为实现IDate接口的每个实体创建分部类. (相同的规则适用于这些部分类,它们必须标记为部分类,与它们扩展的类具有相同的名称并且位于相同的命名空间中)然后在SaveChanges覆盖中

public override int SaveChanges() 
{
         var entities = ChangeTracker.Entries<Entity>() 
                        .Where(e => e.State == EntityState.Added) 
                        .Select(e => e.Entity); 
        var currentDate = DateTime.Now; 
        foreach(var entity in entities) 
        { 
                ***Now cast entity to type of IDate and set your value ***
                entity.Date = currentDate; 
        } 

        return base.SaveChanges(); 
}

我不用Vb写,所以我把语法留在了C#中.

这应该满足您的所有要求.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读