我和我的同事最近讨论了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);
SO。 你怎么看?你会用吗?为什么呢?
谢谢你,很抱歉很长的帖子。
答案 0 :(得分:0)
任何设计模式的优点之一是对其他人的可理解性。我:你是如何设计Web服务的?您:我们正在使用存储库模式。我:好的,我明白了。
虽然这绝不是一个全面的答案,但是当您被要求进行更新时,了解在哪里寻找事物以及需要改变的地方还有很长的路要走。
你所拥有的是一种你喜欢使用的设计模式,但是你应该问问自己其他人是否容易理解。
例如,您有一个名为“Do”的类。作为一个名称,这并没有说明该课程的用途。你的评论表明它“做了些什么”,但其他人是否会直观地了解那里发生了什么?添加和删除显然是“做”的事情,但为什么不是获取或设置?这可能对你有意义,但其他人可能会看到不同的东西。
我假设你在团队中工作。如果您的团队将采用此模式作为模式,那么每个人都需要同意使用它,并且为此,每个人都需要直观地理解它是如何工作的,更重要的是,如何扩展它。如果他们不这样做,那么你将开始在你的Do类中找到你认为不应该存在的方法,并且你将把方法放在其他人无法找到的类中,因为他们没有相同的心智模型和你如何运作一样。如果每个人都采取不同的行动,事情就会花费很长时间。
关于使用部分类扩展实体,我会自己避免这种情况。实体有明确的责任,通过向他们添加代码,您将分配额外的职责(参见Single Responsibility Principle)。不可否认,您的额外代码都被分成了单独的静态子类,但如果是这样的话,为什么不简单地将它们自己设置为类并将它们移动到应用程序中的其他位置呢?
就类本身而言,使用静态方法的静态类将使单元测试非常困难,并且没有理由将它们设置为静态,所以我肯定会改变它。当然,现在你必须实例化它们才能使用它们,这为在其他地方移动它们提供了更多的参数。
从技术角度来看,BaseService
在做什么?您正在创建上下文,将按引用(为什么?)传递给AddPost
(例如),然后将其用作out
中的BaseService.Add
参数。我不确定这里发生了什么,但看起来不对。
作为一种模式,我认为它需要工作,但仅仅通过尝试一种模式,你正在朝着正确的方向前进。
你没有提到你的同事认为'良好做法',但我建议你继续讨论,直到你同意为止。决定你想要达到的目标,以及最适合的模式。也许有一种既定的模式适合,但尽量不要过度工程化。我的经验告诉我,我越是试图从实体框架中抽象出来,就越难以使用它的一些更强大的功能。