EF Core – 冷知识

Add vs AddAsync

参考: 

.NET 5 REST API Tutorial

AddAsync() vs Add() in EF Core

EF Core’s AddAsync v. Add Method

EF Core in ASP.NET Core - CRUD

无意间再看视频的时候, 看见有人使用 AddAsync. 在我的认知 Add 只是修改了 local 的 entity, SaveChangesAsync 才会链接数据库.

所以按道理, Add 不需要 Async 丫. 虽然说 "有 Async 就尽量用 Async“ 是没错, 但是不直观丫. 

于是搜了一下. 结论是 AddAsync 是用于那些需要 auto generate id 之类的情况的. 很冷门的情况啦. 

所以绝大部分情况下是不需要的, 那用 Async 会伤性能吗, 有 ValueTask 所以是不会的. 但即便如此,为了更好的了解, 我建议是用 Add 就好了.

 

ValueGenerated

参考: Generated Values

Value Generated 讲的就是那种 default value 或者 SQL trigger 维护的值.

一共有 5 个方法

ValueGeneratedNever 是用来覆盖 EF Core 默认行为的, 比如 primary key 默认就是 auto generate 的, 这个很少会用到

ValueGeneratedOnUpdateSometimes, 这个我没有看懂什么意思, sometimes? 没有找到相关资料. 

ValueGeneratedOnAdd 这个就是说在 insert 的时候 SQL 会负责 generate value, 但是如果我们在 entity 有 set value 的话, 它会用我们的 value 哦, 不清楚是不是 bug (v6.0 测试是这样)... 但是 by right 我们不应该给 value 啦

ValueGeneratedOnUpdate 就是说在 update 的时候 SQL 会负责 generate value, 所以 EF 会无视 entity 的 value, 你改了也没用. 它不会反应到 SQL 语句里的.

ValueGeneratedOnAddOrUpdate 就是 Add + Update, 一起, 奇怪应该叫 And 而不是 Or 吧... set 了这个之后 insert 的时候即使 Entity 有 value 也没用了, 它会无视.

当设置了 ValueGenerated 以后, 在 insert/update 后, EF 会去跑 select 把新的值拿来 update entity, 但是它不支持跨 Entity 啦, 比如你 update Entity A, 但是 SQL trigger update B Table, 然后 Entity B 是不会被更新的.

 

When unique + nullable EF will auto add filter

当 unique + nullable 时, EF 会自动帮我们添加 filter... 如果不希望它自作聪明的话, 可以把它关掉.

but 如果是 clustered EF 就不会加 filter 了哦.

 

Double apply duplicated where

假如我写了一模一样的 where 语句. EF 是否会过滤掉呢? 

var query1 = _db.Products.Where(e => e.Status == ProductStatus.Other);
var query2 = query1.Where(e => e.Status == ProductStatus.Other);

当然是不会啦

拿 SQL Server 会不会过滤呢? 很可能是会的, 毕竟 SQL 有词法优化步骤, 比如 where 的顺序对 SQL 来说并不重要

Does the order of where clauses matter in SQL?

为什么我会研究这个呢? 因为我在做权限过滤, 需要对 OData query 做过滤. 我想先过滤 odata query 然后再过滤权限. 因为这样会比较快 (我的业务啦). 于是在 Controller 里跑了 ODataQueryOptions.Apply

但结果发现, 在 EnableQuery.OnActionExecuted 时它依然会 apply 多一次, 就造成了上面的结果. 但最后发现原来顺序不重要, 那就可以先过滤权限, 再交由 EnableQuery.OnActionExecuted 执行 Apply 了. 瞎操心一场.

 

How function be translated in query?

有个 String 和 DateTime

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public DateTime Date { get; set; }
}

Where query 的时候调用 function

public static string GetMyValue() => "test";

var products = db.Products.Where(e => e.Name == GetMyValue() && e.Date == DateTime.Now.AddDays(1)).ToList();

翻译结果

WHERE ([p].[Name] = N'test') AND ([p].[Date] = DATEADD(day, CAST(1.0E0 AS int), GETDATE()))

EF Core 在解析表达式时先调用 GetMyValue 获取到了 test, 而 DateTime.Now.AddDays 则直接翻译成了 SQL 语句.

 

posted @ 2021-10-25 22:22  兴杰  阅读(576)  评论(0编辑  收藏  举报