我正在使用以下设计:
我正在将AutoMapper用于域/ DTO转换(双向),Entity Framework Code First和SQL Server 2012。
每个表都有一个名为RowVersion
且类型为timestamp
的字段,以检查更新。
我使用DTO层是因为我的域对象无法在WCF服务中序列化,并且我的域层中有一个循环。
无论如何,我的问题是,在创建Bank
(UI中只有一个表的一个表)时,我将值(BankCode,BankName)复制到BankDTO
中,并且在我的服务层中将BankDTO
转换为BankDomain
(Bank
的实体域对象)使用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();
如果我在
BankDto
和BankBranchDto
中映射BankDomain
和BankBranchDomain
而不是使用Mapper.Map
,则SaveChanges
可以工作-但我必须使用AutoMapper。 最佳答案
您需要先添加已更改的对象或值,然后保存更改。
db.Banks.AddObject(---your object name or value which you want to add---);
db.SaveChanges();