Add simultaneity two object depend on each other - linq

I am newbie in linq.
I am building a web api project with net core.
This is what i am trying to deal with:
I had two tables: "1" as document and "2" as caisse.
In the same query, I want to add table 1 and table 2.
The problem is that I do not know the id of the table 2. the id is Auto-increment.
I had the idea to get the Max id but i think this is a not appropriate solution.
how can i solve this problem ?
[HttpPost("addDocument")]
public IActionResult AddShoppingCart([FromBody]DocumentDto document)
{
if (Document== null)
{
return BadRequest();
}
try
{
Caisse caisse = new Caisse();
caisse.dateDocumentRelease=Date.now();
caisse.dateOfAmount=Date.now();
_iCaisseService.AddCaisse(caisse)
// here i don't konw the id of the caisse after adding it
_iDocumentService.AddDocument(document);
if (!_iDocumentService.Save())
{
return StatusCode(500, "A problem happened while handling your request.");
}
return StatusCode(200, "good"); }
catch (Exception ex)
{
return StatusCode(500, "A problem happened while handling your request.");
}
}

public Document AddCaisse(Caisse caisse)
{
return _context.Caisse .Add(caisse).Entity;
}
this linq query solve the problem.
At the post method, i call the addCaisse.
var object= _iDocumentService.addCaisse(caisse);
return Ok(object.Id);

Related

How can I catch the error and output an empty list instead? Spring Boot

I have the following problem:
I have built a filter with Spring Boot that searches for the locations by its externalId or name. If I enter parts of the name as filterCriteria then I get the right results. But if I enter something wrong as filterCriteria then I get back the below listed "404 Not found". I would rather get back an empty list because of the error.
How can I catch the error and output an empty list instead?
My Controller
#Override
public ResponseEntity<List<SolarPanelLocation>> getSolarPanelLocationsByIdAndName(String solarPanelNameAndExternalId) {
return ResponseEntityBuilderUtils.ok(solarPanelService.getSolarPanelFilterByExternalIdAndSolarPanelName(solarPanelNameAndExternalId));
}
My Service
#Override
public List<SolarPanelLocation> getSolarPanelFilterByExternalIdAndSolarPanelName(String solarPanelNameAndExternalId) {
if (solarPanelNameAndExternalId == null) {
throw new MissingValueException("The externalId or solarPanelName are required");
}
final List<SolarPanelLocationEntityView> solarPanelLocationEntityListFilter = solarPanelLocationDAO.filterSolarPanelList(
solarPanelNameAndExternalId);
if (solarPanelLocationEntityListFilter == null) {
throw new NoSuchElementFoundException("Structure Group Location list not available");
}
if (solarPanelLocationEntityListFilter.isEmpty()) {
throw new NoSuchElementFoundException("Solar Panel Location list not available");
}
return solarPanelLocationMapper.map(solarPanelLocationEntityListFilter);
}
My DAO with Query
#Query("SELECT d FROM SolarPanelLocationEntityView d WHERE d.externalId LIKE %:#{#filterCriteria}% OR lower(d.solarPanelName) LIKE lower(concat('%',:filterCriteria,'%')) ")
List<SolarPanelLocationEntityView> filterSolarPanelList(#Param("filterCriteria") String filterCriteria);
My Postman result
{
"status": 404,
"message": "Solar Panel Location list not availablen"
}
SOLUTION
if (solarPanelLocationEntityListFilter.isEmpty()) {
return List.of();
}
Problem solved. I just had to play in the service not the error code, but an empty list.
if (solarPanelLocationEntityListFilter.isEmpty()) {
return List.of();
}

Function that returns a bool result and show errors in case of a false return

I want to have a function that validate an object.
In case of a false result I want to know the reason why my object isn't valid.
This is a sample algorithm:
public bool ValidObject(MyObjectClass obj)
{
if(obj==null)
{
throw Exception("obj cannot be null");
return false;
}
if(obj.A=='x'){
throw Exception("obj cannot be x");
return false;
}
....
....
// other validations
....
...
if(obj.Students.Count()==100)
{
throw Exception("some error message");
return false;
}
return true;
}
If I call my function:
if(ValidateObject(this.Obj))
{
InsertIntoDB(this.Obj);
}
else
{
//do something
}
I will get an error if my object is invalid. But I dont't want this.
But maybe in some cases I want to know the reason why my object is invalid.
I don't want to make to functions that do the same but one of them throw exceptions. I don't think is a right approach.
So, my first thought was to make the previous function private and to create another public function:
public bool ValidObject2(MyObjectClass obj, bool withErrors=false)
{
try
{
return ValidObject(obj);
}
catch(Exception ex)
{
if(withErrors)
{
throw ex;
}
return false;
}
}
What do you think? Do you have other ideas ?
The Rails way:
Have a method save which saves to the DB, and, in case of validation errors, just holds on to them without raising an exception.
Provide a getter validation_errors which returns a list of the errors in the previous save.
Make a trivial method save_with_validation which first calls save and then raises an exception if and only if validation_errors returns a non-empty set of errors. (Depending on your language, you might be able to get away with a shorter name like save!)

ASP.Net Web API POST to table with just a single identity column

I have a table with a single identity column, where I need to send a POST request and be able to retrieve the identity value that was generated.
My codes are as below:
// POST: api/XXXX
[ResponseType(typeof(MyFileDTO))]
public IHttpActionResult PostMyFile(MyFile myFile)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.MyFile.Add(myFile);
db.SaveChanges();
var dto = new MyFileDTO()
{
FileId = myFile.FileId
};
return CreatedAtRoute("DefaultApi", new { id = myFile.FileId }, dto);
}
I am struggling a bit to test this POST call through Postman.
So, is there a proper way to create a POST api call similar to the situation described above where the only column is an identity?
Thanks.
** (Update) Additional Info:**
I am getting an error on the line:
db.MyFile.Add(myFile);
db.SaveChanges();
Where it is saying that value cannot be null, but I am not quite sure what value would need to be added here, as this is an identity column...
Found out a way to get around this.
Pretty much have the codes as below:
// POST: api/XXXX
[ResponseType(typeof(MyFileDTO))]
public IHttpActionResult PostMyFile(MyFile myFile)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.MyFile.Add(myFile);
db.SaveChanges();
// Get the highest myFile value.
long maxMyFileId = db.MyFile.Max(p => p.MyFileId)
var dto = new MyFileDTO()
{
FileId = maxMyFileId
};
return Ok(Dto);
}
Not sure if this is the proper way, but for now, it seems to resolve my issue of being able to obtain the column value.
Would appreciate any other answer if available.

unit testing a Delete controller method

I am trying to test the delete method from my controller.
I have the following test case:
[TestMethod()]
[DeploymentItem("Courses.sdf")]
public void RemoveCourseConfirmedTest()
{
CoursesController target = new CoursesController();
int id = 50;
ActionResult actual;
CoursesDBContext db = new CoursesDBContext();
Course courseToDelete = db.Courses.Find(id);
List<CourseMeet> meets = db.Meets.Where(a => a.courseID == id).ToList();
actual = target.RemoveCourseConfirmed(courseToDelete);
foreach (CourseMeet meet in meets)
{
Assert.IsFalse(db.Meets.Contains(meet));
}
Assert.IsFalse(db.Courses.Contains(courseToDelete));
}
This is the controller method
[HttpPost, ActionName("RemoveCourse")]
public ActionResult RemoveCourseConfirmed(Course course)
{
try
{
db.Entry(course).State = EntityState.Deleted;
db.SaveChanges();
return RedirectToAction("Index");
}
catch (DbUpdateConcurrencyException)
{
return RedirectToAction("RemoveMeet", new System.Web.Routing.RouteValueDictionary { { "concurrencyError", true } });
}
catch (DataException)
{
ModelState.AddModelError(string.Empty, "Unable to save changes. Try again.");
return View(course);
}
}
However when I run the test case I get the following exception.
System.InvalidOperationException: An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
I ran the test through the debugger and found that the problem in on the following line:
db.Entry(course).State = EntityState.Deleted;
I am not sure why this is happening.
The biggest problem I see here is that you are testing directly against the database. Your unit tests should mock out the database dependencies especially.
However, if you are deadset on doing it this way, then the error you are getting is coming from the fact that your test is opening a CoursesDBContext, and then your code under test appears to be using its own CoursesDBContext. So, the error is because you cannot try to reference the same entity from different contexts. You will need some way of passing in your context to your class (either a public property or being passed through the parameters)

MVC3 binding nested model using Entity Framework with GUID keys

I have been fighting with this all day and still I am failing.
I can simplify the problem as follows:
I have reports and reports have forms. I have entity models of each. They have Guid id's as shown below.
I am trying to get a single view where I can create a report and a form. As an end goal I would like to be able to add multiple forms, but just one would be great. My controller is as follows:
// GET: /AllInOne/Create
public ActionResult Create()
{
ViewBag.PossibleReportBases = reportBaseRepository.All;
ViewBag.PossibleCategories = categoryRepository.All;
var model = new Report {FromDate = DateTime.Now};
model.Forms.Add(new Form());
return View(model);
}
// POST: /AllInOne/Create
[HttpPost]
public ActionResult Create(Report report)
{
if (ModelState.IsValid) {
reportRepository.InsertOrUpdate(report);
reportRepository.Save();
return RedirectToAction("Index");
}
else
{
ViewBag.PossibleReportBases = reportBaseRepository.All;
ViewBag.PossibleCategories = categoryRepository.All;
return View();
}
}
The repository code looks like this:
public void InsertOrUpdate(Report report)
{
if (report.Id == default(System.Guid)) {
// New entity
report.Id = Guid.NewGuid();
context.Reports.AddObject(report);
} else {
// Existing entity
context.Reports.Attach(report);
context.ObjectStateManager.ChangeObjectState(report, EntityState.Modified);
}
}
At one stage the binding was giving me this error:
The EntityCollection has already been initialized. The InitializeRelatedCollection method should only be called to initialize a new EntityCollection during deserialization of an object graph.
I have tried many things for the views, but none of them have worked.
Please help.
i dont' think you need to bother with the attaching. if you've selected the report from your context, it is already being tracked. you can simplify your repository like so
public void InsertOrUpdate(Report report)
{
// i prefer Guid.Empty but no big deal
if (report.Id == default(System.Guid)) {
// New entity
report.Id = Guid.NewGuid();
context.Reports.AddObject(report);
}
context.SaveChanges();
}

Resources