Tôi đang cố gắng để có một Id
lớp học được đánh máy mạnh mẽ , hiện đang giữ 'dài' trong nội bộ. Thực hiện dưới đây. Vấn đề tôi gặp phải khi sử dụng điều này trong các thực thể của mình là Entity Framework cho tôi một thông báo rằng Id thuộc tính đã được ánh xạ lên nó. Xem IEntityTypeConfiguration
dưới đây của tôi .
Lưu ý: Tôi không hướng đến việc thực hiện DDD cứng nhắc. Vì vậy, hãy ghi nhớ điều này khi bình luận hoặc trả lời . Toàn bộ id đằng sau bản đánh máy Id
là dành cho các nhà phát triển đến dự án mà họ mạnh mẽ sử dụng Id trong tất cả các thực thể của họ, tất nhiên được dịch thành long
(hoặc BIGINT
) - nhưng sau đó thì rõ ràng cho những người khác.
Bên dưới lớp & cấu hình, không hoạt động. Repo có thể được tìm thấy tại https://github.com/KodeFoxx/Kf.CleanArch architectureTemplate.NetCore31 ,
Id
lớp tại (đã nhận xét ngay bây giờ): https://github.com/KodeFoxx/Kf.CleanArch architectureTemplate.NetCore31 / blob / master / Source / Common / Kf.CANetCore31 / DomainDrivenDesign / Id.csEntity
vàValueObject
các lớp (trong đó đối với mộtEntity
thuộc tínhId
là loạiId
.cs (ở trên): https://github.com/KodeFoxx/Kf.CleanArch architectureTemplate.NetCore31 / trip / master / Source / Community / Kf.CANetCore31 / DomainDrivenDesign- Các cấu hình tại: https://github.com/KodeFoxx/Kf.CleanArchitectTemplate.NetCore31/tree/master/Source/Inrabase/Persistence/Kf.CANetCore31.Infr kia.Persistence.Ef/Entity
Id
triển khai lớp (đã bị đánh dấu lỗi thời, vì tôi đã từ bỏ ý tưởng cho đến khi tôi tìm thấy giải pháp cho việc này)
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
Tôi đã sử dụng khi Id không được đánh dấu lỗi thời cho thực thểPerson
Tuy nhiên, thật không may, khi loại Id, EfCore không muốn ánh xạ nó ... khi loại dài thì không có vấn đề gì ... như các loại thuộc sở hữu khác, như bạn thấy (với Name
) làm việc tốt
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
lớp cơ sở (khi tôi vẫn đang sử dụng Id, vì vậy khi nó không được đánh dấu lỗi thời)
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
(tên miền và tài liệu tham khảo cho ValueObjects khác có thể được tìm thấy tại https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31/tree/master/Source/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
..., hoặc sẽ phải triển khai nó theo cách khác trong một phương thức mở rộng sau đó ... Tôi thích ý tưởng này, thx để suy nghĩ cùng. Nếu không có giải pháp nào khác được đưa ra, tôi sẽ giải quyết vấn đề này, vì điều này nêu rõ ý định.