【发布时间】:2018-09-23 16:40:07
【问题描述】:
我正在研究 ASP.NET 样板。我有一个问题,我尝试从名为Buildings 的表中获取记录并对其进行更新。我通过以下方式从数据库中获取记录:
var buildingApp = _buildingsAppService.getBuildingsById(buildingInput);
然后,我对数据进行了一些更改,如下所示:
buildingApp.streetName = Request["buildingaddress"];
buildingApp.isInHoush = Convert.ToBoolean(Request["buildingOutput.isInHoush"]);
buildingApp.houshName = Request["HoushName"];
然后将buildingApp复制到另一个具有相同属性的对象中,以便将新对象传递给update方法,如下所示:
var updateBuildingInput = new UpdateBuidlingsInput()
{
Id = buildingApp.Id,
buildingID = buildingApp.buildingID,
numOfBuildingUnits = buildingApp.numOfBuildingUnits,
numOfFloors = buildingApp.numOfFloors,
streetName = buildingApp.streetName,
buildingNo = buildingApp.buildingNo,
neighborhoodID = buildingApp.neighborhoodID,
buildingTypeID = buildingApp.buildingTypeID,
GISMAP = buildingApp.GISMAP,
houshProperty = buildingApp.houshProperty,
houshName = buildingApp.houshName,
X = buildingApp.X,
Y = buildingApp.Y,
buildingName = buildingApp.buildingName,
isInHoush = buildingApp.isInHoush,
buildingUsesID = buildingApp.buildingUsesID
};
而update方法如下:
_buildingsAppService.update(updateBuildingInput);
问题是当它执行上一行时,我得到以下错误:
System.InvalidOperationException:“附加类型为“TaawonMVC.Models.Buildings”的实体失败,因为同一类型的另一个实体已经具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图形,然后将非新实体的状态设置为“未更改”或“已修改”。
我可以看到,当我手动初始化对象updateBuildingInput 时,update 方法运行没有错误。但是当它依赖于使用buildingApp从数据库中获取的对象时,就会发生错误。似乎get 方法从数据库中获取数据并继续保留数据库中的记录,当我尝试更新同一记录时,就会发生冲突。这是所有get 和update 发生的整个动作:
public ActionResult UpdateApplication (UpdateApplicationsInput model)
{
var updateApplication = new UpdateApplicationsInput();
updateApplication.buildingId = Convert.ToInt32(Request["buildingnumber"]);
updateApplication.buildingUnitId = Convert.ToInt32(Request["dropDownBuildingUnitApp"]);
//==== get building and unit related to application for update ======
var buildingInput = new GetBuidlingsInput()
{
Id = updateApplication.buildingId
};
var buildingUnitInput = new GetBuildingUnitsInput()
{
Id = updateApplication.buildingUnitId
};
var buildingApp = _buildingsAppService.getBuildingsById(buildingInput);
var buildingUnitApp = _buildingUnitsAppService.GetBuildingUnitsById(buildingUnitInput);
buildingApp.streetName = Request["buildingaddress"];
buildingApp.isInHoush = Convert.ToBoolean(Request["buildingOutput.isInHoush"]);
buildingApp.houshName = Request["HoushName"];
// buildingUnitApp.BuildingId = updateApplication.buildingId;
buildingUnitApp.ResidenceStatus = Request["residentstatus"];
// copy object getBuildingUnitInput to updateBuildingUnitInput
var updateBuildingUnitInput = new UpdateBuildingUnitsInput()
{
BuildingId = buildingUnitApp.BuildingId,
ResidentName = buildingUnitApp.ResidentName,
ResidenceStatus = buildingUnitApp.ResidenceStatus,
NumberOfFamilyMembers = buildingUnitApp.NumberOfFamilyMembers,
Floor = buildingUnitApp.Floor,
UnitContentsIds = buildingUnitApp.UnitContentsIds
};
//============================================
// copy object from getBuildingOutput to updateBuildingInput
var updateBuildingInput = new UpdateBuidlingsInput()
{
Id = buildingApp.Id,
buildingID = buildingApp.buildingID,
numOfBuildingUnits = buildingApp.numOfBuildingUnits,
numOfFloors = buildingApp.numOfFloors,
streetName = buildingApp.streetName,
buildingNo = buildingApp.buildingNo,
neighborhoodID = buildingApp.neighborhoodID,
buildingTypeID = buildingApp.buildingTypeID,
GISMAP = buildingApp.GISMAP,
houshProperty = buildingApp.houshProperty,
houshName = buildingApp.houshName,
X = buildingApp.X,
Y = buildingApp.Y,
buildingName = buildingApp.buildingName,
isInHoush = buildingApp.isInHoush,
buildingUsesID = buildingApp.buildingUsesID
};
//======================================================
updateApplication.Id = Convert.ToInt32(Request["applicationId"]);
updateApplication.fullName = model.fullName;
updateApplication.phoneNumber1 = model.phoneNumber1;
updateApplication.phoneNumber2 = model.phoneNumber2;
updateApplication.isThereFundingOrPreviousRestoration = model.isThereFundingOrPreviousRestoration;
updateApplication.isThereInterestedRepairingEntity = model.isThereInterestedRepairingEntity;
updateApplication.housingSince = model.housingSince;
updateApplication.previousRestorationSource = model.previousRestorationSource;
updateApplication.interestedRepairingEntityName = model.interestedRepairingEntityName;
updateApplication.PropertyOwnerShipId = Convert.ToInt32(Request["PropertyOwnerShip"]);
updateApplication.otherOwnershipType = model.otherOwnershipType;
updateApplication.interventionTypeId = Convert.ToInt32(Request["interventionTypeName"]);
updateApplication.otherRestorationType = model.otherRestorationType;
updateApplication.propertyStatusDescription = model.propertyStatusDescription;
updateApplication.requiredRestoration = model.requiredRestoration;
updateApplication.buildingId = Convert.ToInt32(Request["buildingnumber"]);
updateApplication.buildingUnitId = Convert.ToInt32(Request["dropDownBuildingUnitApp"]);
// ==== get of restoration types which it is multi select drop down list ======
var restorationTypes = Request["example-getting-started"];
string[] restorationTypesSplited = restorationTypes.Split(',');
byte[] restorationTypesArray = new byte[restorationTypesSplited.Length];
for (var i = 0; i < restorationTypesArray.Length; i++)
{
restorationTypesArray[i] = Convert.ToByte(restorationTypesSplited[i]);
}
updateApplication.restorationTypeIds = restorationTypesArray;
// ====== end of RestorationTypes
_buildingsAppService.update(updateBuildingInput);
_applicationsAppService.Update(updateApplication);
// _buildingUnitsAppService.Update(updateBuildingUnitInput);
// ==== get list of applications ==============
var applicationsUpdate = _applicationsAppService.getAllApplications();
var applicationsViewModel = new ApplicationsViewModel()
{
Applications = applicationsUpdate
};
return View("Applications", applicationsViewModel);
}
我使用的 ASP.NET Boilerplate 模板如何对数据库进行 CRUD 操作:
public class BuildingsManager : DomainService, IBuildingsManager
{
private readonly IRepository<Buildings> _repositoryBuildings;
public BuildingsManager(IRepository<Buildings> repositoryBuildings)
{
_repositoryBuildings = repositoryBuildings;
}
// create new building in table buildings .
public async Task<Buildings> create(Buildings entity)
{
var building = _repositoryBuildings.FirstOrDefault(x => x.Id == entity.Id);
if(building!=null)
{
throw new UserFriendlyException("Building is already exist");
}
else
{
return await _repositoryBuildings.InsertAsync(entity);
}
}
// delete a building from buildings table .
public void delete(int id)
{
try
{
var building = _repositoryBuildings.Get(id);
_repositoryBuildings.Delete(building);
}
catch (Exception)
{
throw new UserFriendlyException("Building is not exist");
}
}
public IEnumerable<Buildings> getAllList()
{
return _repositoryBuildings.GetAllIncluding(b => b.BuildingType, n => n.NeighboorHood,u=>u.BuildingUses);
}
public Buildings getBuildingsById(int id)
{
return _repositoryBuildings.Get(id);
}
public void update(Buildings entity)
{
_repositoryBuildings.Update(entity);
}
}
我该如何解决这个问题?非常感谢您的帮助。
【问题讨论】:
-
您好!更新前试试这个代码:
_buildingsAppService.Entry(updateBuildingInput).State = EntityState.Modified; -
核心层,CRUD操作数据库使用IRepository向数据库注入语句:
-
您不需要将更新的对象复制到另一个对象。一旦您对对象
buildingApp进行了更改,如果您想立即更新它,您可以调用SaveChanges(),或者直接返回,当请求完成时,工作单元会自动为您更新它。
标签: c# asp.net asp.net-mvc entity-framework aspnetboilerplate