Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有统一和实体框架的UnitOfWork_C#_.net_Entity Framework_Dependency Injection_Unity Container - Fatal编程技术网

C# 具有统一和实体框架的UnitOfWork

C# 具有统一和实体框架的UnitOfWork,c#,.net,entity-framework,dependency-injection,unity-container,C#,.net,Entity Framework,Dependency Injection,Unity Container,您好,我正在使用Unity来管理我的服务层,而服务层又与管理所有存储库的UnitOfWork通信 我的一些服务调用其他服务,我的问题是如何在服务层之间传递相同的工作单元 在我的例子中,所有控制器操作都是从GUI在计时器上的每个按钮操作或事件上启动的,这就是为什么我有一个工厂按需创建UnitOfWork,但这会导致问题,因为我不知道如何在服务之间传递此UnitOfWork 特别困难的是知道如何将这个特定的UnitOfWork实例注入到服务构造函数中。请注意,一些服务可能会长时间运行(在后台线程上运

您好,我正在使用Unity来管理我的服务层,而服务层又与管理所有存储库的UnitOfWork通信

我的一些服务调用其他服务,我的问题是如何在服务层之间传递相同的工作单元

在我的例子中,所有控制器操作都是从GUI在计时器上的每个按钮操作或事件上启动的,这就是为什么我有一个工厂按需创建UnitOfWork,但这会导致问题,因为我不知道如何在服务之间传递此UnitOfWork

特别困难的是知道如何将这个特定的UnitOfWork实例注入到服务构造函数中。请注意,一些服务可能会长时间运行(在后台线程上运行10分钟左右),我不知道这是否会对设计产生任何影响

当前,从另一个服务调用的服务正在创建自己的工作单元,这会导致事务设计和实体框架实体跟踪出现问题

非常欢迎您的建议

class OtherService : IOtherService
{
    public OtherService(IUnitOfWorkFactory unitOfworkFactory, 
        ISettingsService settingsService)
    {
        UnitOfWorkFactory = unitOfworkFactory;
        SettingsService = settingsService;
    }
    IUnitOfWorkFactory UnitOfWorkFactory;
    ISettingsService SettingsService;

    function SomeSeviceCall()
    {
        // Perhaps one way is to use a factory to instantiate a 
        // SettingService, and pass in the UnitOfWork here?
        // Ideally it would be nice for Unity to handle all of 
        // the details regardless of a service being called from
        // another service or called directly from a controller
        // ISettingsService settingsService = 
        //     UnityContainer.Resolve<ISettingService>();

        using (var uow = UnitOfWorkFactory.CreateUnitOfWork())
        {
            var companies = uow.CompaniesRepository.GetAll();
            foreach(Company company in companies)
            {
                settingsService.SaveSettings(company, "value");
                company.Processed = DateTime.UtcNow();
            }
            uow.Save();
        }
    }
}

class SettingsService : ISettingsService
{
    public SettingsService(IUnitOfWorkFactory unitOfworkFactory)
    {
        UnitOfWorkFactory = unitOfworkFactory;
    }
    IUnitOfWorkFactory UnitOfWorkFactory;

    // ISettingsService.SaveSettings code in another module...
    function void ISettingsService.SaveSettings(Company company, 
        string value)
    {
        // this is causing an issue as it essentially creates a 
        // sub-transaction with the new UnitOfWork creating a new 
        // Entiy Framework context
        using (var uow = UnitOfWorkFactory.CreateUnitOfWork())
        {
            Setting setting = new Setting();
            setting.CompanyID = company.CompanyID;
            setting.SettingValue = value;
            uow.Insert(setting);
            uow.Save();
        }
    }
}
class OtherService:IOtherService
{
公共其他服务(IUnitOfWorkFactory unitOfworkFactory、,
i设置服务设置(服务)
{
UnitOfWorkFactory=UnitOfWorkFactory;
设置服务=设置服务;
}
IUNITOF工厂联合工厂;
i设置服务设置服务;
函数SomeSeviceCall()
{
//也许一种方法是使用工厂来实例化
//设置服务,并在这里传递工作单元?
//理想情况下,Unity处理所有这些问题会很好
//无论从何处调用服务,都会显示详细信息
//另一个服务或直接从控制器调用
//i设置服务设置服务=
//UnityContainer.Resolve();
使用(var uow=UnitOfWorkFactory.CreateUnitOfWork())
{
var companies=uow.CompaniesRepository.GetAll();
foreach(公司中的公司)
{
设置服务保存设置(公司,“值”);
company.Processed=DateTime.UtcNow();
}
uow.Save();
}
}
}
类设置服务:ISettingsService
{
公共设置服务(IUnitOfWorkFactory unitOfworkFactory)
{
UnitOfWorkFactory=UnitOfWorkFactory;
}
IUNITOF工厂联合工厂;
//ISettingsService.SaveSettings代码位于另一个模块中。。。
函数void ISettingsService.SaveSettings(公司,
字符串值)
{
//这导致了一个问题,因为它本质上造成了
//具有新UnitOfWork的子事务创建新的
//实体框架上下文
使用(var uow=UnitOfWorkFactory.CreateUnitOfWork())
{
设置=新设置();
setting.CompanyID=company.CompanyID;
setting.SettingValue=值;
uow.插入(设置);
uow.Save();
}
}
}

您可以使用某种“当前”工作单元,它绑定到当前线程并在服务代码中显式解析。您需要类来保存UoW的线程静态实例来实现这一点。然而,这不是一个很好的解决方案。

嗨,我一直在努力解决这个问题,这就是我想到的

公共类UnitOfWorkFactory
{
私有静态只读哈希表_threads=new Hashtable();
私有常量字符串HTTPCONTEXTKEY=
“AboutDbContext.UnitOfWorkFactory”;
公共静态IUnitOfWork创建()
{
IUnitOfWork unitOfWork=GetUnitOfWork();
if(unitOfWork==null | | unitOfWork.IsDisposed)
{
unitOfWork=新unitOfWork();
保存unitOfWork(unitOfWork);
}
返回工作单元;
}
公共静态IUnitOfWork GetUnitOfWork()
{
if(HttpContext.Current!=null)
{
if(HttpContext.Current.Items.Contains(HTTPCONTEXTKEY))
{
返回(IUnitOfWork)HttpContext
.Current.Items[HTTPCONTEXTKEY];
}
返回null;
}
var thread=thread.CurrentThread;
if(string.IsNullOrEmpty(thread.Name))
{
thread.Name=Guid.NewGuid().ToString();
返回null;
}
锁定(_threads.SyncRoot)
{
return(IUnitOfWork)_threads[Thread.CurrentThread.Name];
}
}
私有静态void SaveUnitOfWork(IUnitOfWork unitOfWork)
{
if(HttpContext.Current!=null)
{
HttpContext.Current.Items[HTTPCONTEXTKEY]=工作单元;
}
其他的
{
锁定(_threads.SyncRoot)
{
_threads[Thread.CurrentThread.Name]=工作单元;
}
}
}
公共静态无效处理工作(IUnitOfWork unitOfWork)
{
if(HttpContext.Current!=null)
{
HttpContext.Current.Items.Remove(HTTPCONTEXTKEY);
}
其他的
{
锁定(_threads.SyncRoot)
{
_threads.Remove(Thread.CurrentThread.Name);
}
}
}
}
公共接口IUnitOfWork:IDisposable
{
无效提交();
bool IsDisposed{get;}
}
公共类UnitOfWork:MyContext
{
}
公共抽象类存储库
:i位置,可在T:class处识别
{
私有工作单元(上下文);
私有UnitOfWork上下文
{
得到
{
if(_context==null ||_context.IsDisposed)
return _context=GetCurrentUnitOfWork();
返回上下文;
}
}
公共TunitoWork GetCurrentUnitOfWork()
工作地点:I工作地点
{
返回(TunitoWork)UnitOfWorkFactory.GetUnitOfWork();
}
公共IEnumerable Get(表达式谓词)
{
返回Context.Set().Where(谓词).ToList();
}
公共布尔存在(表达式谓词