Published on

EF Core 使用 PostgreSQL Array 型別

一般在儲存多筆資料到 DB 的時候都會開另一個 Table 來存放,要使用的話就要使用 Join 的方式來拿取,在 PostgreSQL 裡面有一個 Array 的資料型別可以讓我們方便的來儲存這類型的資料,來看如何在 EF Core 裡面使用 PostgreSQL Array 型別

EF Core 2.2 ASP.NET Core 2.2 PostgreSQL 11.0

DbContext

  • 在 DbContext 裡面有一個 User 物件,裡面有一個型別為 string arrayPhones
public class AppDbContext : DbContext
{
	public AppDbContext(DbContextOptions<AppDbContext> options)
	: base(options)
	{
	}

	public DbSet<User> User { get; set; }
}

public class User
{
	public int Id { get; set; }

	public string Name { get; set; }

	public string[] Phones { get; set; }
}
  • 使用 EF Core 的 migrations 到 DB
    • 可以看到在 DB 裡面的型別為 text array

必須要注意的是在 C# 的型別要使用 string array 而不能是 List<string>,如果是使用 List 的話,相關的 Array 操作是無法轉譯成 SQL Command 的

新增

  • 先新增一筆資料到 DB
public void Insert()
{
    _dbContext.User.Add(new User
    {
        Id = 1,
        Name = "Cash",
        Phones = new[] { "1234", "5678" }
    });
    _dbContext.SaveChanges();
}
  • 產生的 SQL Command

  • 查看 Table
    • 可以看到 DB 裡面的表示方式是使用 { }

修改

  • 修改前面新增到 DB 的資料
public void Update()
{
	var user = _dbContext.User.FirstOrDefault(a => a.Id == 1);
	user.Phones = user.Phones.Append("4321").ToArray();

    _dbContext.SaveChanges();
}
  • 產生的 SQL Command

查詢

  • 使用 Contains 查詢
 _dbContext.User.Where(a => a.Phones.Contains("1234"))
  • 產生的 SQL Command

  • 取出單筆資料查詢
_dbContext.User.Where(a => a.Phones[0] == "1234")
  • 產生的 SQL Command

  • 使用 SequenceEqual 查詢
    • 基本上就是比對兩個 Array 是不是相等,而且順序要相同
_dbContext.User.Where(a => a.Phones.SequenceEqual(new[] { "1234", "5678", "4321" }))
  • 產生的 SQL Command

  • 長度查詢
_dbContext.User.Where(a => a.Phones.Length == 3)
  • 產生的 SQL Command

後記

  • 可以看到使用 PostgreSQL 的 Array 實在是相當的方便,可以大幅的減少程式碼,而且查詢也都是使用原生的 SQL Query,效能應該也是不錯才是
  • 現階段的查詢 API 目前只支援上面這四種轉譯成 SQL Command,希望之後可以在多一些