我正在使用以下设计:



我正在将AutoMapper用于域/ DTO转换(双向),Entity Framework Code First和SQL Server 2012。

每个表都有一个名为RowVersion且类型为timestamp的字段,以检查更新。

我使用DTO层是因为我的域对象无法在WCF服务中序列化,并且我的域层中有一个循环。

无论如何,我的问题是,在创建Bank(UI中只有一个表的一个表)时,我将值(BankCode,BankName)复制到BankDTO中,并且在我的服务层中将BankDTO转换为BankDomainBank的实体域对象)使用AutoMapper,然后调用SaveChange

那行得通,我也可以更新银行。

但是,当我编辑一个Bank和一个银行分支,然后将BankDTO转换为BankDomain并调用SaveChange时,那是行不通的。如果我在没有AutoMapper的情况下将BankDTO映射到BankDomain,则可以正常工作并执行更新。

我的BankDTO看起来像这样:

[Serializable]
public class BankModel
{

    public BankModel()
    {
        this.BankBranches = new List<BankBranchModel>();
    }
    public int? Id { get; set; }
    public byte[] RowVersion { get; set; }
    public decimal BankCode { get; set; }
    public string BankName { get; set; }
    public string LatinCode { get; set; }

    public virtual ICollection<BankBranchModel> BankBranches { get; set; }

}


BankBranch DTO:

[Serializable]
public class BankBranchModel
{

    public BankBranchModel()
    {

    }

    public int BankId { get; set; }
    public decimal BranchCode { get; set; }
    public string BranchName { get; set; }
    public int? ExecutiveUnitId { get; set; }
    public int? Id { get; set; }
    public byte[] RowVersion { get; set; }
    public BankModel Bank { get; set; }

}


BankDomain

public class Bank : BaseEntity
{
    public Bank()
    {
        this.BankBranches = new List<BankBranch>();
    }
    public decimal BankCode { get; set; }
    public string BankName { get; set; }
    public string LatinCode { get; set; }

    public virtual ICollection<BankBranch> BankBranches { get; set; }
}


BankBranchDomain

public class BankBranch : BaseEntity
{
    public BankBranch()
    {
    }
    public int BankId { get; set; }
    public decimal BranchCode { get; set; }
    public string BranchName { get; set; }

    public virtual Bank  Bank { get; set; }
}


SQL表是这样创建的:

CREATE TABLE [global].[Bank](
[Id] [int] NOT NULL,
[RowVersion] [timestamp] NOT NULL,
[BankCode] [numeric](18, 0) NOT NULL,
[BankName] [varchar](20) NOT NULL,
[LatinCode] [varchar](3) NOT NULL,
    CONSTRAINT [PKBnk] PRIMARY KEY CLUSTERED
    (
        [Id] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
            ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 ) ON [PRIMARY]

CREATE TABLE [global].[BankBranch](
[Id] [int] NOT NULL,
[RowVersion] [timestamp] NOT NULL,
[BranchCode] [numeric](18, 0) NOT NULL,
[BranchName] [varchar](100) NOT NULL,
[BankId] [int] NOT NULL,
[ExecutiveUnitId] [int] NULL,
    CONSTRAINT [PK_BankBranch] PRIMARY KEY CLUSTERED
    (
        [Id] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
            ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]


以及更新代码:

using (var db = new AndishmandTestContext())
{
    Mapper.CreateMap<BankModel, Bank>();
    Mapper.CreateMap<Bank, BankModel>();

    Mapper.CreateMap<BankBranchModel, BankBranch>();
    Mapper.CreateMap<BankBranch, BankBranchModel>();

    var oldb = db.Banks.Include("BankBranches").Where(b => b.Id == 1);
    Bank bank = oldb.FirstOrDefault();
    BankModel bankmodel = new BankModel();
    Mapper.Map(bank, bankmodel);
}


在UI层中更改BankModel之后,此代码在服务层中执行:

var Newb = db.Banks.Include("BankBranches").Where(b => b.Id == 1);
Bank newbank = Newb.FirstOrDefault();
Mapper.Map(bankmodel, newbank);


然后将更改保存在业务层中:

db.SaveChanges();


如果我在BankDtoBankBranchDto中映射BankDomainBankBranchDomain而不是使用Mapper.Map,则SaveChanges可以工作-但我必须使用AutoMapper。

最佳答案

您需要先添加已更改的对象或值,然后保存更改。

  db.Banks.AddObject(---your object name or value which you want to add---);
   db.SaveChanges();

10-08 03:22