EntityFramework Core personal memo
I put it in text on my desktop, but I thought I’d lose it, so make a note.
- Please do not refer to
⓪ DB Maigure
-
First time
Enable-Migrations -
Create update file
Add-Migration Post Name -
Run
Update-Database -Verbose
Entity Framework Core annotation
(1) [NotMapped]: Model property that is not added to the DB
② Primary key
For single unit: [Key]
modelBuilder.Entity
③ Automatic data generation
[DatabaseGenerated(DatabaseGeneratedOption.None)]
Not automatically generated (useful if you want to set the primary key etc. as you like?)
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
Automatically allocated when a record is added
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
Automatically allocated at the time of additional update
④ Not Null constraint
[Required]
⑤ Maximum length
[MaxLength(500)]
⑥ Optimistic exclusive control
DbUpdateConcurrencyException occurs
[Timestamp]: The line where the time stamp is saved when the line is updated and added.
Exclude check target → DbUpdateConcurrencyException occurs
⑦ Shadow property
It’s not defined in the model, but it can be used as a property of the model! What is that?
modelBuilder.Entity
How to Use
context.Entry (variable containing the model) .Property (“shadow property name”). CurrentValue = DateTime.Now;
var XXXX = context.XXXX.OrderBy (b => EF.Property
⑧ Relationship
https://docs.microsoft.com/ja-jp/ef/core/modeling/relationships
A. Fully defined relationship
sample.cs
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
I. Foreign key property
sample.cs
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public Blog Blog { get; set; }
}
C. Single navigation property
sample.cs
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
}
D. Data annotation
(1) When the name of the foreign key does not depend on the naming such as a fully defined relationship
[Foreign Key (“Foreign Key Name”)]
sample.cs
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogForeignKey { get; set; }
[ForeignKey("BlogForeignKey")]
public Blog Blog { get; set; }
}
(2) When two links are set from one model to the same model
[InverseProperty (“property name of linked model”)]
sample.cs
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int AuthorUserId { get; set; }
public User Author { get; set; }
public int ContributorUserId { get; set; }
public User Contributor { get; set; }
}
public class User
{
public string UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[InverseProperty("Author")]
public List<Post> AuthoredPosts { get; set; }
[InverseProperty("Contributor")]
public List<Post> ContributedToPosts { get; set; }
}
E. Composite foreign key (do you have to use Fluent?)
modelBuilder.Entity
F. Many-to-many
sample.cs
class MyContext : DbContext
{
public DbSet<Post> Posts { get; set; }
public DbSet<Tag> Tags { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<PostTag>()
.HasKey(t => new { t.PostId, t.TagId });
modelBuilder.Entity<PostTag>()
.HasOne(pt => pt.Post)
.WithMany(p => p.PostTags)
.HasForeignKey(pt => pt.PostId);
modelBuilder.Entity<PostTag>()
.HasOne(pt => pt.Tag)
.WithMany(t => t.PostTags)
.HasForeignKey(pt => pt.TagId);
}
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public List<PostTag> PostTags { get; set; }
}
public class Tag
{
public string TagId { get; set; }
public List<PostTag> PostTags { get; set; }
}
public class PostTag
{
public int PostId { get; set; }
public Post Post { get; set; }
public string TagId { get; set; }
public Tag Tag { get; set; }
}
⑨INDEX
modelBuilder.Entity
⑩ Automatic property backing field
When expanding from DB, it is written directly to the backing field without using an accessor (it seems)
sample.cs
public class Blog
{
private string _url; //← The naming convention for this is_<camel-cased property name>Or m_<camel-cased property name>
public int BlogId { get; set; }
public string Url
{
get { return _url; }
set { _url = value; }
}
}
⑪ Value conversion
It is saved under the name of Enum in the example. What is the usage? ??
sample.cs
public class Rider
{
public int Id { get; set; }
public EquineBeast Mount { get; set; }
}
public enum EquineBeast
{
Donkey,
Mule,
Horse,
Unicorn
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Rider>()
.Property(e => e.Mount)
.HasConversion(
v => v.ToString(),
v => (EquineBeast)Enum.Parse(typeof(EquineBeast), v));
}
⑫ Owned entity type
Can be used like a nest. One real table
sample.cs
[Owned]
public class StreetAddress
{
public string Street { get; set; }
public string City { get; set; }
}
public class Order
{
public int Id { get; set; }
public StreetAddress ShippingAddress { get; set; }
}
OnModelCreating
sample.cs
#region OwnsOne
modelBuilder.Entity<Order>().OwnsOne(p => p.ShippingAddress);
#endregion
#region OwnsOneString
modelBuilder.Entity<Order>().OwnsOne(typeof(StreetAddress), "ShippingAddress");
#endregion
#region ColumnNames
modelBuilder.Entity<Order>().OwnsOne(
o => o.ShippingAddress,
sa =>
{
sa.Property(p => p.Street).HasColumnName("ShipsToStreet");
sa.Property(p => p.City).HasColumnName("ShipsToCity");
});
#endregion
After that, restrictions on the DB
⑭ Table mapping
sample.cs
[Table("blogs")]
[Table("blogs", Schema = "blogging")] //Schema settings
⑮ nvarchar (max) column mapping
sample.cs
[Column("blog_id")]
⑯ Data type
[Column(TypeName = “varchar(200)”)] decimal(5, 2) nvarchar(max) DateTime
The types that can be used differ depending on the DB
⑰ Primary key
[Key]
If you want to name
sample.cs
modelBuilder.Entity<Blog>()
.HasKey(b => b.BlogId)
.HasName("PrimaryKey_BlogId");
⑱ Default schema
sample.cs
modelBuilder.HasDefaultSchema("blogging");
⑲ Calculation column
A calculation column cannot be created in the DB, but how can it be used?
sample.cs
class MyContext : DbContext
{
public DbSet<Person> People { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>()
.Property(p => p.DisplayName)
.HasComputedColumnSql("[LastName] + ', ' + [FirstName]");
}
}
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string DisplayName { get; set; }
}
⑳ Sequence
- Not associated with a specific table
sample.cs
modelBuilder.HasSequence<int>("OrderNumbers");
㉑ Default value Initial value
sample.cs
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Rating)
.HasDefaultValue(3);
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public int Rating { get; set; }
}
- You can also use SQL fragments.
sample.cs
.HasDefaultValueSql("getdate()");
㉒ Index
sample.cs
modelBuilder.Entity<Blog>()
.HasIndex(b => b.Url)
.HasName("Index_Url");
㉓ Filter
sample.cs
modelBuilder.Entity<Blog>()
.HasIndex(b => b.Url)
.HasFilter("[Url] IS NOT NULL");
㉔ Foreign key constraint
sample.cs
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Post>()
.HasOne(p => p.Blog)
.WithMany(b => b.Posts)
.HasForeignKey(p => p.BlogId)
.HasConstraintName("ForeignKey_Post_Blog");
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}