gpt4 book ai didi

c# - 我们可以使用枚举作为类型安全的实体 ID 吗?

转载 作者:可可西里 更新时间:2023-11-01 03:11:07 26 4
gpt4 key购买 nike

我们在 EF 6.1 代码优先设置中使用一个相当大的模型,我们使用 int 作为实体 ID。

不幸的是,这并不像我们希望的那样类型安全,因为很容易混淆 id,例如比较不同类型实体的 id (myblog.Id == somePost.Id) 或类似的。或者更糟:myBlog.Id++。

因此,我想出了使用类型化 ID 的想法,因此您不能混淆 ID。所以我们的博客实体需要一个 BlogId 类型。现在,显而易见的选择是使用一个包含在结构中的 int,但您不能将结构用作键。而且你不能扩展 int... - 等等,你可以!使用枚举!

所以我想到了这个:

public enum BlogId : int { } 
public class Blog
{
public Blog() { Posts = new List<Post>(); }
public BlogId BlogId { get; set; }
public string Name { get; set; }
public virtual List<Post> Posts { get; set; }
}
internal class BlogConfiguration : EntityTypeConfiguration<Blog>
{
internal BlogConfiguration()
{
HasKey(b => b.BlogId);
Property(b=>b.BlogId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}

现在我们有了类型安全的 ID——比较 BlogId 和 PostId 是一个编译时错误。我们不能将 3 添加到 BlogId。空枚举可能看起来有点奇怪,但这更多是一个实现细节。我们必须在映射中显式设置 DatabaseGeneratedOption.Identity 选项,但这是一次性的工作。

在我们开始将所有代码转换为该模式之前,是否存在任何明显的问题?

编辑:我可能需要澄清为什么我们必须首先使用 id 而不是完整的实体。有时我们需要匹配 EF Linq 查询中的实体 - 比较实体在那里不起作用。例如(建立在博客示例上并假设一个更丰富的领域模型):查找当前用户博客条目的评论。请记住,我们想在数据库中执行此操作(我们有大量数据)并且我们假设没有直接的导航属性。并且未附加 currentUser。一个天真的方法是

from c in ctx.Comments where c.ParentPost.Blog.Author == currentUser 

这不起作用,因为您无法比较 EF Linq 中的实体。所以我们尝试

from c in ctx.Comments where c.ParentPost.Blog.Id == currentUser.Id

这编译并运行但错误 - 它应该是

from c in ctx.Comments where c.ParentPost.Blog.Author.Id == currentUser.Id

Typesafe ids 会捕捉到它。我们有比这更复杂的查询。尝试“查找由特定其他用户对当前用户博客条目发表的评论,而当前用户自己后来没有评论过”。

问候,尼尔斯

最佳答案

这是一种有趣的方法,但问题是:它值得吗?结果是什么?

你仍然可以做类似的事情

 if ((int)blog.BlogId == (int)comment.CommentId) { }

就我个人而言,我会投入更多时间在教育人员、编写良好的测试和代码审查上,而不是试图添加某种形式的额外复杂性来影响您使用和查询实体的方式。

思考——例如:

  • 此转换对 LINQ 查询的性能有何影响?
  • 如果您通过 WCF 的 Web API 公开您的操作,您将如何实现?
  • 这是否适用于导航属性?
  • 此外,您可以用作主键的类型有限;我认为这不适用于 Guids。

一种额外保护的方法是让您的域层通过接受实体实例而不是 ID 来处理这些类型的事情。

关于c# - 我们可以使用枚举作为类型安全的实体 ID 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23550656/

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