gpt4 book ai didi

c# - Entity Framework Core 中的强类型 ID

转载 作者:行者123 更新时间:2023-12-03 15:10:46 24 4
gpt4 key购买 nike

我正在尝试使用强类型 Id类,现在在内部保持“长”。下面实现。
我在我的实体中使用它的问题是 Entity Framework 给了我一条消息,表明属性 Id 已经映射到它上面。看我的 IEntityTypeConfiguration以下。

注:我的目标不是严格执行 DDD。所以请在评论或回答时记住这一点。键入 Id 后面的整个 ID适用于进入项目的开发人员,他们被强类型化为在所有实体中使用 Id,当然翻译为 long (或 BIGINT )-但对其他人来说很清楚。

在类和配置下面,这是行不通的。
可以在 https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31 找到该存储库。 ,

  • Id类(class)(现已注释掉):https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31/blob/master/Source/Common/Kf.CANetCore31/DomainDrivenDesign/Id.cs
  • EntityValueObject类(对于 Entity,属性 Id 的类型是 Id .cs(上图):https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31/tree/master/Source/Common/Kf.CANetCore31/DomainDrivenDesign
  • 配置地址:https://github.com/KodeFoxx/Kf.CleanArchitectureTemplate.NetCore31/tree/master/Source/Infrastructure/Persistence/Kf.CANetCore31.Infrastructure.Persistence.Ef/EntityTypeConfigurations

  • Id类实现 (现在标记为过时,因为我放弃了这个想法,直到找到解决方案)
    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当 Id 未标记为实体 Person 已过时时,我正在使用不幸的是,当类型为 Id 时,EfCore 不想映射它......当类型为 long 时没有问题......其他拥有的类型,如您所见(使用 Name )工作正常。
    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基类(当我还在使用 Id 时,所以当它没有被标记为过时)
    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 (域和对其他 ValueObject 的引用可以在 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);
    }
    }

    最佳答案

    I am not aiming to have a rigid DDD implementation. So please keep this in mind when commenting or answering. The whole id behind the typed Id is for developers coming to the project they're strongly typed to use Id in all of their entities



    那么为什么不添加一个类型别名:
    using Id = System.Int64;

    关于c# - Entity Framework Core 中的强类型 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60154834/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com