不要迷恋,而要实践

最近,在别人博客的回复上看到讨论Entity Framework性能的问题,有人不知所以人云亦云。说Entity Framework很好,甚至超越ado.net!!!

真的无言以对,对这样的老兄。只能淡淡的微笑了之,就一菜鸟!

说说自己的事,老证明不要迷恋谁,而要实践了解才是正道!

正在写MVC5+Bootstrap+postgreSQL的应用程序,本打算使用Entity Framework,但是总感觉性能差(我的观点,不知道性能问题可以不解决,对于知道的性能差绝对不用),因此使用Npgsql来直接控制数据库。问题出现了,Identity使用Entity Framework。Google了一番,终于找到方案!

在微软的网站上有单独的MySQL存储的项目源码,拿来修改成PostgreSQL数据库的。

1.使用Attribute来实现实体类与数据库之间的Insert和update的SQL语句生成,直接执行SQL即可添加和删除。

原因:为了通用允许派生IdentityUser,而增加的。

2.选择DynamicBuilder<T>作为DataReader转换为List<T>的映射方案

3.测试过其他的转换方案,包括老赵的Fasterflect和其他的库。结果如下:

第一名:老赵Fasterflect文章里面提到的Dynamic库。

第二名:老赵的Fasterflect

当然了,他们都是缓存方式。

100万次相差20毫秒左右。I3上测试的。Release模式!但是不知道为啥在家的机器上I5+8G+win7 64位上发现他们差不多了。

在编写的过程中发现如下的问题:

注册用户的时候

...

var result1 = await UserManager.CreateAsync(user, "123C567&80xx");

...

经过反编译出他的代码


public virtual async Task<IdentityResult> CreateAsync(TUser user, string password)
{
    this.ThrowIfDisposed();
    IUserPasswordStore<TUser, TKey> passwordStore = this.GetPasswordStore();
    if (user == null)
    {
        throw new ArgumentNullException("user");
    }
    if (password == null)
    {
        throw new ArgumentNullException("password");
    }
    IdentityResult identityResult = await this.UpdatePasswordInternal(passwordStore, user, password).WithCurrentCulture<IdentityResult>();
    IdentityResult result;
    if (!identityResult.Succeeded)
    {
        result = identityResult;
    }
    else
    {
        result = await this.CreateAsync(user).WithCurrentCulture<IdentityResult>();
    }
    return result;
}


internal async Task<IdentityResult> UpdatePasswordInternal(IUserPasswordStore<TUser, TKey> passwordStore, TUser user, string newPassword)
{
    IdentityResult identityResult = await this.PasswordValidator.ValidateAsync(newPassword).WithCurrentCulture<IdentityResult>();
    IdentityResult result;
    if (!identityResult.Succeeded)
    {
        result = identityResult;
    }
    else
    {
        await passwordStore.SetPasswordHashAsync(user, this.PasswordHasher.HashPassword(newPassword)).WithCurrentCulture();
        await this.UpdateSecurityStampInternal(user).WithCurrentCulture();
        result = IdentityResult.Success;
    }
    return result;
}


internal async Task UpdateSecurityStampInternal(TUser user)
{
    if (this.SupportsUserSecurityStamp)
    {
        await this.GetSecurityStore().SetSecurityStampAsync(user, UserManager<TUser, TKey>.NewSecurityStamp()).WithCurrentCulture();
    }
}

SetSecurityStampAsync函数中居然调用了UserTable.Update(TUser user)方法,这就糊涂了?

明明是添加用户为啥在添加的过程中居然执行更新用户呢,这当然不能成功,多余的操作。


这是我编写自己的存储是这样!没有看Identity + Entity framework的代码。

因此不要迷恋谁,实践+学习最重要!

可能本人菜,不知道他为啥这么设计!有理解请指教!

### 回答1: 这是描述一个人收集各种干脆面的英雄卡的故事,他曾连续一个月只吃干脆面这一种零食,但有一些卡片却很难找到。后来某商场搞了一次英雄卡兑换活动,你只需要有三张连续编号的英雄卡,就可以换取任意编号的英雄卡。小明想知道他最多可以换到几张英雄卡(新换来的英雄卡不可再次兑换)。 ### 回答2: 小明想要最多换到的英雄卡数量,其实就是最长的连续英雄卡序列的长度。如果我们将所有英雄卡的编号按照从小到大的顺序排列,那么只需要找到最长的连续子序列即可。比如说,假设小明收集到了以下十二张英雄卡: 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15 我们可以将它们按照编号从小到大排列,得到: 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15 然后,我们可以使用一些算法来找到最长的连续子序列。一种比较简单的方式是使用双指针法。我们维护两个指针 left 和 right,分别指向当前连续子序列的起始和终止位置。我们不断向右移动 right 指针,直到遇到一个不连续的位置,此时我们就找到了一个连续子序列。记录该子序列的长度,然后将 left 指针右移一个位置,重新开始查找下一个连续子序列。 在上面的例子中,我们可以依次找到以下连续子序列: 1, 2, 3 5, 6, 7, 8 10, 11, 12, 13 其中最长的连续子序列为 5, 6, 7, 8,长度为 4,也就是小明可以兑换到的最多英雄卡数量。当然,如果小明收集的英雄卡中没有连续的三张编号,那么他就无法参加兑换活动了。 ### 回答3: 小明要想换到最多的英雄卡,就要先收集到尽可能多的编号连续的英雄卡。假设小明手中已经有了n张编号连续的英雄卡,他就可以利用这n张英雄卡来换取更多的英雄卡。 假设小明手中的英雄卡编号为a1, a2, a3,………an。为了得到尽可能多的英雄卡,小明的兑换策略应该是换取距离他现有英雄卡编号最近的编号连续的三张英雄卡。假设他换取了编号连续为b1, b2, b3的英雄卡,那么小明新增的英雄卡数量就是3-1=2张,因为小明已经有了a1, a2, a3这三张英雄卡。 接下来,小明手中的英雄卡编号就变成了a1, a2, a3, b1, b2, b3。后面的英雄卡就可以继续按照这个策略来换取,直到不能再换为止。 假设小明一共收集到了m张英雄卡,并且收集到了k组编号连续的三张英雄卡,那么小明最多可以换到的英雄卡数量为m+k*2。因为小明在每次兑换时可以获取两张新的英雄卡,而兑换次数是k次。 因此,小明最多可以换到的英雄卡数量为收集到的英雄卡总数加上连续三张编号的英雄卡组数乘以2,即: 最多换到的英雄卡数量 = m + k*2 这就是小明最多可以换到的英雄卡数量的公式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值