【问题标题】:How organize layers in a project using Entity Framework?如何使用实体框架组织项目中的层?
【发布时间】:2012-11-10 11:01:19
【问题描述】:

我在组织我的项目方面进退两难。我正在构建一个发送时事通讯的应用程序。我在我的解决方案中将其分为三个项目:Newsletter.UI (WPF)、Newsletter.DALNewsletter.Services。在Newsletter.DAL 中有一些类表示由 EF 在附加文件中增强的实体(它们是部分类) - 覆盖ToString()。在Newsletter.UI 中当然有用于演示的 WPF 项目。我的问题始于Newsletter.Services

现在我创建了MailingListService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newsletter.DAL;

namespace Newsletter.Services
{
    public class MailingListService
    {
        private NewsletterEntities _context;

        public MailingListService()
        {
            _context = new NewsletterEntities();
        }

        public List<string> GetAllMailingListsNames()
        {
            var query = from m in _context.MailingLists select new { m.Name };
            List<string> names = new List<string>();
            foreach (var m in query)
                names.Add(m.Name);
            return names;
        }

        public List<MailingList> GetAllMailingLists()
        {
            var query = from m in _context.MailingLists select m;
            return query.ToList();       
        }
    }
}

MessageService.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newsletter.DAL;
using System.Data.Entity;

namespace Newsletter.Services
{
    public class MessageService
    {
        private NewsletterEntities _context;

        public MessageService()
        {
            _context = new NewsletterEntities();
        }

        public List<Message> GetAllMessages()
        {
            return (from m in _context.Messages select m).ToList();
        }

        public static Message GetMessageByID(int id)
        {
            using (NewsletterEntities context = new NewsletterEntities())
            {
                Message message = (from m in context.Messages where m.MessageID == id select m).FirstOrDefault();
                return message;
            }
        }
    }
}

RecipientService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newsletter.DAL;

namespace Newsletter.Services
{
    public class RecipientService
    {
        private NewsletterEntities _context;
        public RecipientService()
        {
            _context = new NewsletterEntities();
        }
        public void addRecipient(Recipient newRecipient)
        {
            _context.Recipients.AddObject(newRecipient);
        }
    }
}

但是,这会产生问题。当我打开一个创建收件人的窗口时,我创建了一个MailingListService 实例来加载邮件列表的名称。然后当我尝试创建一个新的Recipient 时,我创建了一个RecipientService 实例并尝试添加一个收件人。我收到一个错误,我无法在不同的地方使用上下文。

如何解决这个问题?我的方法不好吗?它应该是什么(服务中应该有什么)?我不想在将来陷入这样的错误。我现在不想学习 MVVM 方法,我需要或多或少地按照我的方式来做这件事。

【问题讨论】:

  • 您看到的确切错误消息是什么?错误发生在哪一行?

标签: wpf entity-framework service-layer


【解决方案1】:

有几种可能的方法:

  1. 对业务事务使用一个上下文实例。上下文应该在服务之外创建,并通过它们的方法或构造函数传递给服务。这将需要一个更高级别的服务(或外观)层来编排较低级别的服务(就像您现在拥有的服务一样)。 IoC 容器可以帮助您创建和注入具有生命周期的上下文,该生命周期绑定到外观服务实例的生命周期。

  2. 分离/附加。在您的 AddRecipient 方法中,首先分离收件人(在检查它是否已附加之后)并将其附加到当前上下文。但是:现在工作单元在 2 个上下文实例之间拆分,您需要一个 TransactionScope 来保持它的事务性。

  3. 在更高级别聚合,例如通过创建一个处理邮件列表、消息和收件人的MailService

  4. 混合方法。具有自己的上下文实例的服务和(最好是无状态的)在其方法签名中具有带有上下文参数的方法的服务(例如public Recipient AddRecipient(NewsletterEntities context, string name, string email)。(通过传递名称等,服务负责创建新的Recipient 对象或返回现有的对象)如果他们已经在那里)。

只是一些想法:)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 2015-06-30
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多