C#对象值与引用赋值问题:ASP.NET Identity改造困惑
问题:用Dapper重写ASP.NET Identity用户系统时的对象赋值问题
我正在用Dapper替代Entity Framework重写ASP.NET Identity用户系统,创建新用户账号时遇到了问题:
- Identity传递过来的
user对象插入数据库后,没有正确的Id值——因为Identity无法知晓数据库当前的自增序列值 - 我通过SQL存储过程插入用户后,会返回刚插入的完整用户数据,将其命名为
retUser
当我单独给Id属性赋值时,网站用户可以正常操作:
user.Id = retUser.Id;
但如果直接给整个user对象赋值,就无法生效:
user = retUser;
我推测这是因为C#是按值赋值,没有真正修改全局的user对象。想请教:C#中是否有单行赋值语句可以实现整对象的引用赋值?或者我是不是误解了问题产生的原因?
核心原因
你的推测是对的,问题本质是C#引用类型的赋值逻辑:
user作为引用类型变量,存储的是堆上对象的内存地址。执行user = retUser时,只是把user这个变量指向的地址换成了retUser的地址,而Identity传入的原始对象根本没被修改——外部代码依然在使用原来的对象,自然拿不到新生成的Id。- 而
user.Id = retUser.Id是直接修改原始对象的属性值,堆上的原对象确实被改变了,所以外部能获取到正确的Id。
可行解决方案
没有单行语句能直接把retUser的所有属性“覆盖”到原user对象上,但可以用这些方法解决:
- 手动复制所有属性
逐个将retUser的属性赋值给原user:user.Id = retUser.Id; user.UserName = retUser.UserName; user.Email = retUser.Email; // 依次复制其他所有需要同步的属性 - 使用对象映射工具
借助AutoMapper这类工具,一行代码完成属性复制(提前配置好映射规则即可):mapper.Map(retUser, user); - 修改方法参数为
ref/out(视场景而定)
如果user是方法的参数,可以将参数声明为ref User user,这样在方法内执行user = retUser时,会修改外部变量的引用。但要注意,ASP.NET Identity的接口签名可能限制这种修改,需要结合你重写的逻辑判断是否可行。
内容的提问来源于stack exchange,提问作者Joshua
相关产品推荐
相关产品推荐

