EF Core 使用 PostgreSQL Array 型別

Posted on 2019-01-08

一般在儲存多筆資料到 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,希望之後可以在多一些