【问题标题】:Is this a good practice for EF Database First?这是 EF Database First 的好习惯吗?
【发布时间】:2017-11-17 13:35:45
【问题描述】:

我和我的同事最近讨论了 EF 的良好做法。 所以我展示了我的一个。

他说有点糊涂。

我的实践在于以特定方式修改自动生成的类。 这是我的起始模型:

namespace PCServer.Data
{
    using System;
    using System.Collections.Generic;

    public partial class Post: IEntity
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Message { get; set; }
        public DateTime Date { get; set; }

        public virtual Post ParentPost { get; set; }
        public virtual AspNetUser Author { get; set; }
    }
}

我喜欢这样扩展:

public partial class Post
    {
        //This class "do" something, like adding a post or deleting a post
        public static class Do
        {
            public static void AddPost(ref ApplicationDbContext context, string postMessage)
            {
                //Create a post
                Post p = new Post();
                p.Title = "This is an example!";
                p.message = postMessage;
                p.Date = DateTime.UtcNow;

                //Adding to context
                BaseService.Add(post, out context);
            }

            public static void DeletePost(ref ApplicationDbContext context, int postId)
            {
                PostRepository postRepo = new PostRepository(context);

                postRepo.GetById(postId);

                //Removing from context
                BaseService.Remove(post, out context);
            }
        }

        //This class "Get" something, like all posts
        public static class Get
        {
            public static void GetPosts()
            {
                using(ApplicationDbContext context = new ApplicationDbContext())
                {
                    PostRepository postRepo = new PostRepository(context);
                    return postRepo.GetAllPosts();
                }
            }
        }

        //This class "Set" something, like title of the post or the post itself maybe
        public static class Set
        {
            public static void Title(ref ApplicationDbContext context, int postId, string title)
            {
                PostRepository postRepo = new PostRepository(context);
                Post post = postRepo.GetById(postId);
                post.Title = title;

                BaseService.Update(post, out context);
            }

            public static void ChangePost(ref ApplicationDbContext context, int postId, Post post)
            {
                PostRepository postRepo = new PostRepository(context);
                Post dbPost = postRepo.GetById(postId);
                dbPost = post;

                BaseService.Update(dbPost, out context);
            }
        }
    }

所以,当我必须对实体做某事时,我可以(仅作为示例):

ApplicationDbContext c = new ApplicationDbContext();

Post.Do.AddPost(ref c,"Hi!");
IEnumerable<Post> posts = Post.Get.GetPosts();

Post.Set.Title(ref c,100,"Changing title!");

毕竟:

await BaseService.CommitAsync<Post>(c);

所以。 你怎么看?你会用吗?为什么?

谢谢你,很抱歉发了这么长的帖子。

【问题讨论】:

  • 可以将其描述为 Active Record 模式。如果它适合您的需求,它是有效的。它不适用于复杂的企业系统。
  • 这个问题是基于意见的,因此是题外话。我的意见?不。这属于服务。

标签: c# entity-framework coding-style forum


【解决方案1】:

任何设计模式的优点之一是对其他人的可理解性。我:你是如何设计你的网络服务的?你:我们正在使用存储库模式。我:好的,我明白了。

虽然这绝不是一个全面的答案,但它有助于了解在哪里查找内容以及当您被要求进行更新时需要更改哪些内容。

你拥有的是你喜欢使用的设计模式,但你应该问问自己它是否容易被别人理解。

例如,您有一个名为“Do”的类。作为一个名字,这并没有说明这个类的用途。您的评论表明它“做某事”,但是其他人会直观地理解其中的内容吗?添加和删​​除显然是“做”的事情,但为什么不是获取或设置?这对你来说可能有意义,但其他人可能会有不同的看法。

我假设您在一个团队中工作。如果你的团队打算采用这种模式,那么每个人都需要同意使用它,而要做到这一点,每个人都需要直观地理解它是如何工作的,更重要的是,如何扩展它。如果他们不这样做,那么您将开始在 Do 类中获取您认为不应该存在的方法,并且您将把方法放在其他人找不到的其他类中,因为他们没有相同的与您一样的心智模型,了解它是如何工作的。如果每个人的做事方式不同,事情很快就会变得一团糟。

关于使用部分类扩展实体,我自己会避免这种情况。实体有明确定义的责任,通过向它们添加代码,您正在分配额外的责任(参见Single Responsibility Principle)。诚然,您的额外代码都被分成单独的静态子类,但如果是这种情况,为什么不简单地让它们成为自己的类并将它们移动到应用程序的其他位置呢?

就类本身而言,具有静态方法的静态类将使单元测试变得极其困难,而且它们没有理由应该是静态的,所以我肯定会改变它。当然,现在您必须实例化它们才能使用它们,这为将它们移动到其他地方提供了更多的论据。

从更专业的角度来说,BaseService 在做什么?您正在创建一个上下文,将其通过引用(为什么?)传递给AddPost(例如),然后将其用作BaseService.Add 中的out 参数。我不确定这里发生了什么,但它看起来不对。

作为一种模式,我会说它需要工作,但只要尝试建立一种模式,你就朝着正确的方向前进。

你没有提到你的同事认为什么是“好的做法”,但我建议你继续讨论这个问题,直到你同意为止。决定你想要达到的目标,以及最适合的模式。也许有一个适合的既定模式,但尽量不要过度设计它。我的经验告诉我,我越是尝试从 Entity Framework 中抽象出来,就越难使用其中一些更强大的功能。

【讨论】:

  • 很好的评论。不幸的是我一个人在这个项目上工作,所以我需要决定一个喜欢我的模式。我不做单元测试,因为我没有做这些的经验。无论如何,谢谢!
  • @ImFlash docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions/… 这里有一篇很好的文章,介绍了可以与 EF 一起使用的模式。另外,我建议学习一些基本的单元测试——你必须以某种方式对其进行测试。这是一个很好的介绍:docs.microsoft.com/en-gb/visualstudio/test/…。最后,如果您对 Stackoverflow 上的答案感到满意,请接受。编码愉快!
  • @ImFlash 顺便说一句,正如其中一位评论者所提到的,这个问题是基于意见的。您可能会发现您会在codereview.stackexchange.com 上发布更多答案。
猜你喜欢
  • 2016-06-27
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-11
  • 2012-09-12
  • 1970-01-01
  • 2021-03-15
相关资源
最近更新 更多