๊ฝค ๊ด์ฐฎ์ ๊ธ์ด ์์ด ๊ณต์ ํฉ๋๋ค.
Avoid Proliferating DbContext or IQueryable in .NET Apps | Blog (ardalis.com)
์์ง
- DbContex, DbSet, IQueryable ์ ๋ฐ์ดํฐ ๋ ์ด์ด ์ธ๋ถ๋ก ๋ ธ์ถ์ํค์ง ๋ง๋ผ.
- Specification ๊ฐ์ฒด๋ก ์ฟผ๋ฆฌ๋ฅผ ํ์ ํ๋ผ.
DbContex, DbSet, IQueryable ์ ์ธ๋ถ๋ก ๋ ธ์ถ์ํค์ง ๋ง๋ผ.
๋ํ์ ์ธ ์ด์ ๋ IQueryable ์ด IEnumerable ์ ํ์ํ๊ณ ์์ด, ์ฌ์ฉ ์ฝ๋์์ IEnumerable๋ก ์ทจ๊ธํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
foreach ๋๋ฆด ๋๋ง๋ค ์ฟผ๋ฆฌ๊ฐ ์ ์ก๋๊ธฐ ํ๊ณ , ์ฌ์ฉ์ ์ฝ๋ ๋จ์์ IEnumerable ์ ํ์ฅ ๋ฉ์๋๋ฅผ ์ ์ํ์ ๊ฒฝ์ฐ, IQueryable ์ ์ฟผ๋ฆฌ๋ก ๋ณํํ๋ ์ฟผ๋ฆฌ ์ปจ๋ฒํฐ๊ฐ ์ด๋ฅผ ํด์ํ ์ ์๊ธฐ ๋๋ฌธ์ ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค.
์ด๋ฐ ๊ฒฝ์ฐ, ์ปดํ์ผ ํ์์ ๋ฌธ์ ๊ฐ ๋๋ฌ๋์ง๋ ์์ต๋๋ค.
Specification ๊ฐ์ฒด๋ก ์ฟผ๋ฆฌ๋ฅผ ํ์ ํ๋ผ.
์๋ ์ฝ๋์ฒ๋ผ ์ํํ ์ฝ๋๋ ์์ฃ .
var allUsers = context.Users.ToList();
์ด๋ฌํ ์ฑ๋ฅ ์ํ์ ์ด๋ํ๋ ์ฝ๋ ๋ฟ๋ง ์๋๋ผ, ์ฝ๋๊ฐ ์ ํ ์์ด ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ๊ฒ ์์ฒด๊ฐ ๋งค์ฐ ์ํํ๋ค๊ณ ์๊ฐํด์์ต๋๋ค. ์ด๋ ์น API ๊ฐ์ ๋๋ฉ์ธ ์ธ๋ถ ๋ ธ์ถ ์ธํฐํ์ด์ค๋ ๋น์ฐํ๊ณ , ๋๋ฉ์ธ ๋ด๋ถ์ ์ฝ๋๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค.
์ด๋ฅผ ์ํด, ๋ฐ์ดํฐ ์๋น์ค๊ฐ DbContext ๋ฅผ ๊ฐ์ธ๊ณ , ํํฐ๋ง๋ ์ธํฐํ์ด์ค๋ง ๋ ธ์ถํ๋ ๊ตฌ์กฐ๋ฅผ ์ฑํํ ์ ์์ต๋๋ค.
sealed class UserService
{
public const int MaxUserRetrieveCount = 50;
private IQueryable<User> _users;
private int _retrieved;
...
public List<User> Next(int count)
{
if (count < 1)
return new();
if (MaxUserRetrieveCount < count)
count = MaxUserRetrieveCount;
var skip = _retrieved;
_retrieved += count;
return _users.Skip(skip).Take(count).ToList();
}
...
}
์ ๋ ์ด ๋ฐฉ๋ฒ์ ์ฃผ๋ก ์ฌ์ฉํด ์๋๋ฐ ๊ฐ์ฅ ํฐ ๋ฌธ์ ๋ ์ ์ง ๋ณด์์ ๋๋ค.
ํํฐ๋ง ์ผ์ด์ค๊ฐ ๋ณ๊ฒฝ/์ถ๊ฐ๋ ๋๋ง๋ค UserService ์ ์ฝ๋๊ฐ ๋ณ๊ฒฝ๋์ด์ผ ํด์ ๊ทธ๋ ์ต๋๋ค.
ํนํ ์ฌ๋ฌ ๊ณณ์์ ํธ์ถ๋๊ณ ์๋ ์ผ์ด์ค๋ฅผ ์์ ํ๋ ค๋ฉด ์์ ํด์ผ ํ ์ฝ๋์ ์์ด ์ฝ๊ฒ ๋ง์์ง๋๋ค.
Specification ํจํด์ ๋จ์ผ ํํฐ๋ง ์ผ์ด์ค๋ฅผ ์บก์ํํ๊ธฐ ๋๋ฌธ์ ์ ์ง๋ณด์ ์ธก๋ฉด์์ ๋งค์ฐ ๋ฐ์ด๋ ๊ฒ ๊ฐ์ต๋๋ค.