2

我正在使用以下设计:

系统架构

我将 AutoMapper 用于域/DTO 转换(两种方式)、Entity Framework Code First 和 SQL Server 2012。

每个表都有一个名为RowVersiontype的字段timestamp,以便检查更新。

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

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

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

但是当我编辑一个Bank和一个银行分行,然后转换BankDTOTOBankDomain和 callSaveChange时,这是行不通的。如果我在没有BankDTOAutoMapper 的情况下映射到,那将起作用并执行更新。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; }

}

BankBranchDTO:

[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();

如果我映射BankDtoandBankBranchDto而不是使用BankDomain,则可以使用 - 但我必须使用 AutoMapper。BankBranchDomainMapper.MapSaveChanges

4

2 回答 2

2

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

  db.Banks.AddObject(---your object name or value which you want to add---);
   db.SaveChanges();
于 2013-04-16T06:17:58.150 回答
2

我找到了我的答案。我改变了我的地图,它醒了

像这样

            Mapper.CreateMap<BankModel, Bank>().ForMember(x => x.BankBranches, opt => opt.Ignore());
            //Mapper.CreateMap<BankModel, Bank>();
            Mapper.CreateMap<Bank, BankModel>();

            Mapper.CreateMap<BankBranchModel, BankBranch>().ForMember(x => x.Bank, opt => opt.Ignore());
            //Mapper.CreateMap<BankBranchModel, BankBranch>();
            Mapper.CreateMap<BankBranch, BankBranchModel>();

然后我最喜欢这样修改我的域

              //update bankdomain
            Mapper.Map(bankmodel, newbank);

            //Update bank branchdomain
            newbank.BankBranches.ToList().ForEach(bb => Mapper.Map(bankmodel.BankBranches.First(c => c.Id == bb.Id), bb));

            //Delete branchdomain
            foreach (var bBmodel in bankmodel.BankBranches.Where(bB => bB.IsDeleted == true))
            {
                newbank.BankBranches.Remove(newbank.BankBranches.Where(bb => bb.Id == bBmodel.Id).First());
            }

            //Add branchdomain
            foreach (var bBM in bankmodel.BankBranches.Where(c => c.Id == null))
            {
                newbank.BankBranches.Add(Mapper.Map<BankBranch>(bBM));
            }

接着

db.SaveChanges();
于 2013-04-16T11:54:37.327 回答