Id
Şimdi 'uzun' dahili olarak tutan güçlü yazılan bir sınıf var çalışıyorum . Aşağıdaki uygulama. Varlıklarımda bunu kullanarak yaşıyorum sorun Entity Framework bana zaten özellik kimliği üzerine eşlenmiş bir mesaj verir olmasıdır. Aşağıya IEntityTypeConfiguration
bakın.
Not: Katı bir DDD uygulaması hedeflemiyorum. Bu yüzden yorum yaparken veya cevaplarken bunu aklınızda bulundurun . Yazılanın arkasındaki tüm kimlik Id
, projeye gelen geliştiricilere yöneliktir, elbette tüm varlıklarında Id'yi kullanmak için güçlü bir şekilde yazıldılar, elbette long
(veya BIGINT
) - tercüme edildi , ancak o zaman diğerleri için açık.
Sınıf ve konfigürasyonun altında, çalışmıyor. Repo https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31 adresinde bulunabilir ,
Id
sınıfı (şimdi yorumlandı): https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31/blob/master/Source/Common/Kf.CANetCore31/DomainDrivenDesign/Id.csEntity
veValueObject
sınıflar (birEntity
mülkId
içinId
.cs (yukarıdaki) türündeydi: https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31/tree/master/Source/Common/Kf.CANetCore31/DomainDrivenDesign- Konfigürasyonlar: https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31/tree/master/Source/Infrastructure/Persistence/Kf.CANetCore31.Infrastructure.Persistence.Ef/EntityTypeConfigurations
Id
sınıf uygulaması (şimdi kullanılmaz olarak işaretlendi, çünkü bunun için bir çözüm bulana kadar fikri terk ettim)
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
Kimlik, varlık için geçersiz olarak işaretlenmediğinde kullanıyordumPerson
Ne yazık ki, Id türünde, EfCore bunu eşlemek istemedi ... uzun zaman ne zaman sorun değildi ... Gördüğünüz gibi diğer sahip olunan türler (ile Name
) İyi çalışmak.
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
temel sınıf (hala Id kullanıyordum, bu yüzden eski olarak işaretlenmediğinde)
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
(alan adı ve diğer ValueObjects referanslarını https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31/tree/master/Source/Core/Domain/Kf.CANetCore31.Core.Domain/People adresinde bulabilirsiniz )
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
... gibi diğer temel sınıf işlevselliğini kaybedecekti ya da bir uzatma yönteminde başka türlü uygulamak zorunda kalacaktım ... Fikri sevdim, birlikte düşünmek için teşekkürler. Başka bir çözüm ortaya çıkmazsa, bunun niyetini açıkça ifade ettiği için, bunun yerine geçebilirim.