我应该将实体(持久性)对象转换为DTO对象吗? - c#

我的项目分层如下:
DAL (Entity)-> BLL (DTO)-> ApplicationComponent (ViewModel)
应用程序(ApplicationComponent)将有多个组件,这些组件将访问BLL。组件包括Windows服务,Web服务,Web API和MVC控制器。
我将NHibernate Entity对象转换为DTO对象,同时将它们从DAL传递到BLL。在将此状态传递给ApplicationComponent时,BLL再次将其转换为ViewModel
这可以帮助我区分关注点以及在每一层中如何处理数据。由于以下原因,我不赞成返回NHibernate Entity对象进行查看:-

数据暴露给我要隐藏的UI(或仅在需要时才暴露),例如密码,用户类型,权限等。
在引用/联接上,访问属性时,NHibernate将执行其他查询,这将使延迟加载的使用无效。
暴露给用户(Entity的)的不必要数据会造成错误的混淆和漏洞。
持久性实现泄漏到BLL / UI中。 Entity不是为UI设计的。它不能在所有情况下都提供UI服务。
我们将DTO属性上的属性用于用户输入验证,对于Entity来说看起来很奇怪。

我使用这种方法面临以下问题:-

最大和明显的问题是具有相似成员和功能的冗余对象。
我必须在每一层中编写映射器方法以转换对象。可以通过使用AutoMapper或类似的方法将其最小化。但是它不能完全解决问题。

问题:-

是否过度分离,应避免(至少将其最小化)?
如果这种方法是正确的,我看不出有任何简单的方法可以完全绕开我上面提到的两个问题。请提出建议。
如果此方法不正确,请提出更正建议。

参考文献:

Link1建议转移Entity对象以查看,据我所知这不是一个好主意。
Link2建议将Entity与我已经在做的DTO映射。
Link3没有帮助。
Link4建议使用类似“自动映射器”工具的工具。但是它仍然不能完全解决问题。
Link5是很棒的帖子。它解释了为什么我应该同意将它们分开。它没有评论如何最大程度地减少由此引起的开销。
Link6不再有用。
Link7是一个很好的答案,建议尽可能使用Entity。它仍然不适用于我的大多数项目。
Linl8是另一个极好的资源,建议像我现在所做的那样以两种方式进行映射。它仍然没有建议最小化开销的方法。

参考方案

您是否考虑过在DTO和实体之间创建共享接口?您不应该将ORM与其他应用程序紧密结合。或者实际上,只要有可能,请使用它们之间的接口以外的任何东西。

从理论上讲,您可以有一个单独的项目,该项目仅包含您希望传递的合同/摘要。为了最大程度地减少映射开销并为扩展保留它,您可以确保实体按预期实现接口(省略不需要的接口),并且在需要定制DTO的情况下,可以使用接口创建带有映射的模型。

添加额外的接口项目时会产生一些开销,但从长远来看,它将使您的代码更整洁,更可维护。

我应该将实体(持久性)对象转换为DTO对象吗? - c#

namespace Data
{
    public class FakeRepo : IFakeRepo
    {
        public IThisIsAnEntity GetEntity()
        {
            return new ThisIsAnEntity();
        }
    }

    public class ThisIsAnEntity : IThisIsAnEntity
    {
        public string HiddenField { get; set; }
        public long Id { get; set; }
        public string SomeField { get; set; }
        public string AnotherField { get; set; }
    }
}

namespace Data.Abstractions
{
    public interface IFakeRepo
    {
        IThisIsAnEntity GetEntity();
    }
}

namespace Abstractions
{
    public interface IThisIsAnEntity : IThisIsAnSlimmedDownEntity
    {
        string SomeField { get; set; }
    }

    public interface IThisIsAnSlimmedDownEntity
    {
        long Id { get; set; }
        string AnotherField { get; set; }
    }
}

namespace Services.Abstractions
{
    public interface ISomeBusinessLogic
    {
        IThisIsAnEntity GetEntity();
        IThisIsAnSlimmedDownEntity GetSlimmedDownEntity();
    }
}

namespace Services
{
    public class SomeBusinessLogic : ISomeBusinessLogic
    {
        private readonly IFakeRepo _repo;

        public SomeBusinessLogic(IFakeRepo repo)
        {
            _repo = repo;
        }

        public IThisIsAnEntity GetEntity()
        {
            return _repo.GetEntity();
        }

        public IThisIsAnSlimmedDownEntity GetSlimmedDownEntity()
        {
            return _repo.GetEntity();
        }
    }
}

namespace UI
{
    public class SomeUi
    {
        private readonly ISomeBusinessLogic _service;

        public SomeUi(ISomeBusinessLogic service)
        {
            _service = service;
        }

        public IThisIsAnSlimmedDownEntity GetViewModel()
        {
            return _service.GetSlimmedDownEntity();
        }

        public IComposite GetCompositeViewModel()
        {
            var dto = _service.GetSlimmedDownEntity();
            var viewModel = Mapper.Map<IThisIsAnSlimmedDownEntity, IComposite>(dto);
            viewModel.SomethingSpecial = "Something else";
            return viewModel;
        }
    }

    
    public class SomeViewModel : IComposite
    {
        public long Id { get; set; }
        public string AnotherField { get; set; }
        public string SomethingSpecial { get; set; }
    }
    
}

namespace UI.Abstractions
{
    public interface IComposite : IThisIsAnSlimmedDownEntity, ISomeExtraInfo
    {

    }

    public interface ISomeExtraInfo
    {
        string SomethingSpecial { get; set; }
    }
}

Spring Data Cassandra的事务管理 - java

我正在使用Spring和Cassandra作为基础数据库。曾提到过弹簧伞项目“ spring data cassandra”。与休眠不同,在这里无法找到如何管理事务。如果您中的某些人已经合并,请共享要包含的事务管理器的详细信息。 参考方案 Cassandra不支持传统(ACID)的事务。在某些特殊情况下,可以通过一些构造来实现事务原子性,例如原子批处理(请参…

从Azure Data Factory执行python脚本 - python

有人可以帮我从Azure数据工厂执行python函数吗?我已经将python函数存储在blob中,并且我试图触发同样的功能。但是我无法做到这一点。请协助。第二,我可以从ADF参数化python函数调用吗? python参考方案 您可能会发现ADF中的Azure Function Activity概念,它允许您在Data Factory管道中运行Azure F…

自动更新ext.data.store上的新数据 - php

我有这个extjs数据存储 mystore= Ext.create('Ext.data.Store', { id: 'store_id', fields: ['label', 'value', 'id', 'type'], autoLoad…

如何使用Spring Data JPA更新实体中的集合字段? - java

假设我有两个实体,它们的字段之间具有@ManyToMany关系。第一个实体称为Pack:@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) @JoinTable(name = "card_in_pack", joinColumns = {@JoinColumn…

更新System.Data.SQLite.dll后,SQLite无效URI - c#

我首先有以下SQLite版本:1.0.77.0(sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.77.0)而且一切正常。将System.Data.SQLite.dll更新到版本1.0.82.0(sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.82.0)…