【问题标题】:Generate new Id based on generic TKey type基于通用 TKey 类型生成新的 Id
【发布时间】:2019-04-10 23:34:07
【问题描述】:

所以,这是我正在构建的引导类库:

class BaseEntity<TKey>
{
    TKey Id { get; set; }
}

interface ICrudRepository<TItem, TKey> where TItem : BaseEntity<TKey>
{
    void Create(TItem item);
}

class MyCrudRepository<TItem, TKey> : ICrudRepository<TItem, TKey> where TItem : BaseEntity<TKey>
{
    IEnumerable<TItem> _items;

    void Create(TItem item) 
    {
        item.Id = GetNewId();
    }

    TKey GetNewId() 
    {
        // what should I do here?

        // with int, this would be 
        // return _items.Select(x => x.Id).DefaultIfEmpty().Max() + 1;
    }
}

我当前的 BaseEntity 没有 ae TKey 参数,而是使用和 INT 来存储项目的密钥,但我如何扩展它以支持泛型类型作为 TKey?说Guid? 例如,我如何处理新项目的生成(参见GetNewId)? 在顺序类型的情况下,它应该只使用现有集合并返回最高数字,但在Guid 上,即它应该只生成另一个

这里是完整代码:https://gitlab.com/demedos/alexander.jsonorm

【问题讨论】:

  • 您唯一的选择是将其保留为抽象并在子类中提供实现,作为练习留给用户。顺便说一句,提供您自己的密钥(而不是让数据库使用自动递增值创建它们)只能真正与 GUID 一起使用,因为几乎不存在与其他客户端生成的 GUID 发生冲突的机会。使用key = oldKey + 1 机制,当您拥有多个数据库客户端时,该方案将进入 s**t。在可能的情况下,将其留给数据库。
  • @spender 我创建这个是为了快速序列化和反序列化 json 项目,repo 链接在问题中。这使得无法在函数之外生成 id
  • @spender 如果客户不知道和 INT 的集合大小,他如何生成 Id?这些项目是否应该作为公共财产公开?
  • 客户端不容易。正如@spender 所说,如果您想在客户端上生成密钥,请使用 GUID。否则,你是在自讨苦吃。如果您绝对必须使用 int,则应使用请求唯一的 id 并将其替换为服务器生成的真正唯一的 id。返回该 id 作为对创建请求的响应的一部分,然后客户端将其映射回来;这种方法存在差距,因为有可能出现问题 - 所以要么接受潜在的数据丢失/孤儿。另一种选择是让客户端保留 ID,然后发出请求。或者,使用 GUID!
  • @spender 请发表您的评论作为答案,以便我将其标记为已接受。现在我已经考虑过了,让消费者生成 id 是有意义的,因为这样可以应用自定义消费者逻辑

标签: c# asp.net .net inheritance


【解决方案1】:

对于cmets,唯一的解决办法就是让消费者根据自己的逻辑和自己的BaseEntity类型来生成ID,所以把GetNewId抽象就够了。 这是相关代码

public class MyCrudRepository<TItem, TKey....etc
{
    [...]

    public abstract TKey GetNewId();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-11
    • 2018-05-22
    • 2011-09-02
    • 2018-12-22
    • 2014-01-02
    • 1970-01-01
    相关资源
    最近更新 更多