我使用以下设计:
我使用AutoMapper进行域/ DTO转换(双向),实体框架代码优先和SQL Server 2012.
每个表都有一个名为RowVersion
的{{1}}类型字段,以便检查更新。
我正在使用DTO层,因为我的域对象无法在WCF服务中序列化,并且我的域层中有一个循环。
无论如何,我的问题是,当创建一个timestamp
(一个在UI中有一个页面的表)时,我将值(BankCode,BankName)复制到Bank
并在我的服务层中转换使用AutoMapper BankDTO
到BankDTO
(BankDomain
的实体域对象),然后调用Bank
。
有效,我也可以更新银行。
但是当我编辑一个SaveChange
和一个银行分行时,请将Bank
转换为BankDTO
并致电BankDomain
,但这不起作用。如果我在没有 AutoMapper的情况下将SaveChange
映射到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; }
}
DTO:
BankBranch
[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
SQL表的创建方式如下:
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; }
}
更新代码:
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]
更改UI层中的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);
}
后,此代码将在服务层中执行:
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
有效 - 但我必须使用AutoMapper。
答案 0 :(得分:2)
您需要先添加已更改的对象或值,然后保存更改。
db.Banks.AddObject(---your object name or value which you want to add---);
db.SaveChanges();
答案 1 :(得分: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();