实体框架无法保存我的更改

时间:2013-04-16 06:11:23

标签: c# wcf entity-framework automapper dto

我使用以下设计:

System architecture

我使用AutoMapper进行域/ DTO转换(双向),实体框架代码优先和SQL Server 2012.

每个表都有一个名为RowVersion的{​​{1}}类型字段,以便检查更新。

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

无论如何,我的问题是,当创建一个timestamp(一个在UI中有一个页面的表)时,我将值(BankCode,BankName)复制到Bank并在我的服务层中转换使用AutoMapper BankDTOBankDTOBankDomain的实体域对象),然后调用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中映射BankBranchDtoBankDomain而不是使用BankBranchDomain,那么Mapper.Map有效 - 但我必须使用AutoMapper。

2 个答案:

答案 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();