Saya mencoba untuk memiliki Id
kelas yang sangat diketik , yang sekarang memegang 'panjang' secara internal. Implementasi di bawah ini. Masalah yang saya alami saat menggunakan ini di entitas saya adalah bahwa Entity Framework memberi saya pesan bahwa ID properti sudah dipetakan di atasnya. Lihat saya di IEntityTypeConfiguration
bawah ini.
Catatan: Saya tidak bermaksud memiliki implementasi DDD yang kaku. Jadi harap ingat hal ini saat berkomentar atau menjawab . Seluruh id di belakang yang diketik Id
adalah untuk pengembang yang datang ke proyek mereka diketik kuat untuk menggunakan ID di semua entitas mereka, tentu saja diterjemahkan ke long
(atau BIGINT
) - tetapi jelas kemudian untuk orang lain.
Di bawah kelas & konfigurasi, yang tidak berfungsi. Repo dapat ditemukan di https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31 ,
Id
class at (berkomentar sekarang): https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31/blob/master/Source/Common/Kf.CANetCore31/DomainDrivenDesign/Id.csEntity
danValueObject
kelas (di mana untukEntity
propertiId
adalah tipeId
.cs (di atas): https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31/tree/master/Source/Common/Kf.CANetCore31/DomainDrivenDesign- Konfigurasi di: https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31/tree/master/Source/Infrastructure/Persistence/Kf.CANetCore31.Infrastructure.Persistence.Ef/EntityTypeConfigurations
Id
implementasi kelas (ditandai sudah usang sekarang, karena saya meninggalkan ide sampai saya menemukan solusi untuk ini)
namespace Kf.CANetCore31.DomainDrivenDesign
{
[DebuggerDisplay("{DebuggerDisplayString,nq}")]
[Obsolete]
public sealed class Id : ValueObject
{
public static implicit operator Id(long value)
=> new Id(value);
public static implicit operator long(Id value)
=> value.Value;
public static implicit operator Id(ulong value)
=> new Id((long)value);
public static implicit operator ulong(Id value)
=> (ulong)value.Value;
public static implicit operator Id(int value)
=> new Id(value);
public static Id Empty
=> new Id();
public static Id Create(long value)
=> new Id(value);
private Id(long id)
=> Value = id;
private Id()
: this(0)
{ }
public long Value { get; }
public override string DebuggerDisplayString
=> this.CreateDebugString(x => x.Value);
public override string ToString()
=> DebuggerDisplayString;
protected override IEnumerable<object> EquatableValues
=> new object[] { Value };
}
}
EntityTypeConfiguration
Saya menggunakan ketika Id tidak ditandai usang untuk entitasPerson
Sayangnya, ketika dari tipe Id, EfCore tidak ingin memetakannya ... ketika tipe lama itu tidak masalah ... Tipe yang dimiliki lainnya, seperti yang Anda lihat (dengan Name
) bekerja dengan baik.
public sealed class PersonEntityTypeConfiguration
: IEntityTypeConfiguration<Person>
{
public void Configure(EntityTypeBuilder<Person> builder)
{
// this would be wrapped in either a base class or an extenion method on
// EntityTypeBuilder<TEntity> where TEntity : Entity
// to not repeated the code over each EntityTypeConfiguration
// but expanded here for clarity
builder
.HasKey(e => e.Id);
builder
.OwnsOne(
e => e.Id,
id => {
id.Property(e => e.Id)
.HasColumnName("firstName")
.UseIdentityColumn(1, 1)
.HasColumnType(SqlServerColumnTypes.Int64_BIGINT);
}
builder.OwnsOne(
e => e.Name,
name =>
{
name.Property(p => p.FirstName)
.HasColumnName("firstName")
.HasMaxLength(150);
name.Property(p => p.LastName)
.HasColumnName("lastName")
.HasMaxLength(150);
}
);
builder.Ignore(e => e.Number);
}
}
Entity
kelas dasar (ketika saya masih menggunakan ID, jadi ketika itu tidak ditandai usang)
namespace Kf.CANetCore31.DomainDrivenDesign
{
/// <summary>
/// Defines an entity.
/// </summary>
[DebuggerDisplay("{DebuggerDisplayString,nq}")]
public abstract class Entity
: IDebuggerDisplayString,
IEquatable<Entity>
{
public static bool operator ==(Entity a, Entity b)
{
if (ReferenceEquals(a, null) && ReferenceEquals(b, null))
return true;
if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
return false;
return a.Equals(b);
}
public static bool operator !=(Entity a, Entity b)
=> !(a == b);
protected Entity(Id id)
=> Id = id;
public Id Id { get; }
public override bool Equals(object @object)
{
if (@object == null) return false;
if (@object is Entity entity) return Equals(entity);
return false;
}
public bool Equals(Entity other)
{
if (other == null) return false;
if (ReferenceEquals(this, other)) return true;
if (GetType() != other.GetType()) return false;
return Id == other.Id;
}
public override int GetHashCode()
=> $"{GetType()}{Id}".GetHashCode();
public virtual string DebuggerDisplayString
=> this.CreateDebugString(x => x.Id);
public override string ToString()
=> DebuggerDisplayString;
}
}
Person
(domain dan referensi ke ValueObjects lain dapat ditemukan di https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31/tree/master/Core/Domain/Kf.CANetCore31.Core.Domain/People )
namespace Kf.CANetCore31.Core.Domain.People
{
[DebuggerDisplay("{DebuggerDisplayString,nq}")]
public sealed class Person : Entity
{
public static Person Empty
=> new Person();
public static Person Create(Name name)
=> new Person(name);
public static Person Create(Id id, Name name)
=> new Person(id, name);
private Person(Id id, Name name)
: base(id)
=> Name = name;
private Person(Name name)
: this(Id.Empty, name)
{ }
private Person()
: this(Name.Empty)
{ }
public Number Number
=> Number.For(this);
public Name Name { get; }
public override string DebuggerDisplayString
=> this.CreateDebugString(x => x.Number.Value, x => x.Name);
}
}
Id.Empty
..., atau harus mengimplementasikannya jika tidak dalam metode ekstensi kemudian ... Saya suka idenya, terima kasih untuk berpikir bersama. Jika tidak ada solusi lain yang muncul saya akan puas dengan ini, karena ini jelas menyatakan niat.Jadi setelah lama mencari, dan mencoba mendapatkan lebih banyak jawaban, saya menemukannya, ini dia. Terima kasih kepada Andrew Lock.
ID yang diketik dalam EF Core: Menggunakan ID entitas yang diketik dengan kuat untuk menghindari obsesi primitif - Bagian 4 : https://andrewlock.net/strongly-typed-ids-in-ef-core-using-strongly-typed-entity- id-untuk-menghindari-primitif-obsesi-bagian-4 /
TL; DR / Ringkasan Andrew Dalam postingan ini saya menjelaskan solusi untuk menggunakan ID yang sangat diketik dalam entitas EF Core Anda dengan menggunakan pengonversi nilai dan pemilih nilai IV kustomConverterSelektor. ValueConverterSelector dasar dalam kerangka Core EF digunakan untuk mendaftarkan semua konversi nilai bawaan antara tipe primitif. Dengan berasal dari kelas ini, kita dapat menambahkan konverter ID yang sangat diketik ke dalam daftar ini, dan mendapatkan konversi tanpa batas di seluruh kueri EF Core kami
sumber
Saya pikir Anda kurang beruntung. Kasing penggunaan Anda sangat jarang. Dan EF Core 3.1.1 masih berjuang dengan menempatkan SQL ke dalam basis data yang tidak rusak apa pun kecuali sebagian besar kasus dasar.
Jadi, Anda harus menulis sesuatu yang melewati pohon LINQ dan ini kemungkinan adalah pekerjaan yang luar biasa, dan jika Anda menemukan bug di EF Core - yang akan Anda - bersenang-senang menjelaskannya di tiket Anda.
sumber