WCF数据服务/实体框架:记录客户端的用户名、身份验证、授权

本文关键字:用户 客户端 身份验证 授权 记录 服务 数据 实体 框架 WCF | 更新日期: 2023-09-27 18:02:36

我正在使用WCF数据服务实体框架,我在我的数据库中有以下表:

表合同
  • Id (int)
  • 名称(varchar)
  • byUser (varchar)
  • isDeleted(钻头)

实体框架类

  • Id (int)
  • 名称(字符串)
  • byUser (string)
  • isDeleted(布尔)

每当用户插入/更新/删除合约时(通过客户端应用程序),我需要记录是谁做了这个操作。

因此,我为插入/更新/删除创建了存储过程,当执行插入/删除/更新时,它将从客户机接收用户名。

问题是删除操作没有发送执行该操作的人:

        var ctx = Context;
        var contractToDelete = ctx.Contracts.Where(c => c.ContractId == 1).First();
        contractToDelete.ByUser = username;
        ctx.DeleteObject(contractToDelete);
        ctx.SaveChanges();

在服务器端,byUser总是null。

问题:

1)如何使byUser参数被发送到服务器?

有更好的方法来处理这种情况吗?(日志/认证/授权)使用实体框架

WCF数据服务/实体框架:记录客户端的用户名、身份验证、授权

它不发送null "always"。它总是发送旧的值。这是实体框架中的一些内部逻辑。对于每个跟踪对象,EF同时保留原始值和当前值。当你删除对象EF不使用当前值-它使用原始值(不要问我为什么,简单地说这就是它的工作方式)。

所以你需要欺骗EF:

var ctx = Context;
var contractToDelete = ctx.Contracts.Where(c => c.ContractId == 1).First();
contractToDelete.ByUser = username;
ctx.Contracts.ApplyOriginalValues(contractToDelete);
ctx.DeleteObject(contractToDelete);
ctx.SaveChanges();

调用ApplyOriginalValues将强制EF用parameter =中传递的值覆盖原始值,您将用当前值覆盖原始值。

在我看来,更好的方法是将删除的记录存储在单独的表中,因为它可以避免将isDeleted=false传递给每个查询的很多问题,其中渴望和延迟加载都将加载删除的记录。避免isDeleted问题的唯一方法是使用条件映射,但在这种情况下,即使您想要,也无法加载已删除的记录,除非您使用存储过程或直接SQL查询。

我的管理方法是,当我的用户登录时,我在会话中存储关于他们的基本信息。然后,我有一个类,它位于我对上下文的操作之上。

每当我提交更改时,我都要通过相同的例程来检查更改的内容。我开发了基于正在处理的实体触发操作的能力(所以我可以关注诸如合同之类的东西)。然后我就有了可以登录的用户。

[编辑]

这比我意识到的更难解释,但我会尝试。

我正在创建一个web应用程序。大量使用Ninject

当用户登录时,我将他们的信息存储在IUserSession对象中(这实际上是在Session中保存的,但是一个自定义的Ninject作用域使这对我来说很简洁,并且防止我必须将数据层暴露给Web Session)。这个用户会话对象包含用户名、用户id等。

我创建了一个包含上下文的类,并包装了所有的SELECT、CREATE、DELETE和COMMIT调用。即选择;

public IQueryable<TEntity> All<TEntity>( ) {
  return Context.Set<TEntity>();
}

这个类也有一个Commit方法,这是对SaveChanges的调用。

在调用SaveChanges之前,您可以以Context.ChangeTracker.Entities

的形式访问更改

对于每个已更改的实体,您可以测试它是否被添加、删除或修改。获取被修改元素的类型;

Type baseEntityType = ObjectContext.GetObjectType( entity.Entity.GetType( ) );

根据我的个人经验,我打算很快写一个教程,