MongoDB basic (Relation between two objects) - asp.net

I am totally new in mongoDB.
I have two objects :
public class BusinessUnit{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Address{ get; set; } = string.Empty;
}
public class Review
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public decimal Rating { get; set; } = 0;
public BusinessUnit BusinessUnit { get; set; }
}
N.B : Please ignore other properties in given images.
I have a business unit and want to save a review document with that business unit.
I save it successfully. But I am facing a problem.
My problem is after saving a BusinessUnit and review (with that business unit) when I update my BusinessUnit's Name it is unchanged in review document.
I want to know why it's happened.
Am I missing something?
Below is my documents.
Thanks in advance.

MongoDB does not work like Relational databases. So if it is updating in one collection, it wont affect other collection data. No idea where ASP.net internally handles the updation process. Otherwise you need to rethink about your design.

Related

Entity Framework Core - optional foreign key

I am creating a web api that needs to return details about vehicles. The first part works fine, just returning data from my vehicles table. Now I have another table which may or may not contain additional data about vehicles in the first table. So when I get vehicle data, I want all of the vehicle data, and any additional data from the second table if it exists, like a left join in SQL.
Here are my classes (very much abridged for readability):
public class Vehicle
{
[Key]
[Required]
public string registrationNo { get; set; }
public string capacity{ get; set; }
public string maxGross{ get; set; }
}
public class VehicleDvlaDetail
{
[ForeignKey("Vehicle")]
public string? registrationNumber { get; set; }
public int? co2Emissions { get; set; }
}
And in my context class OnModelCreating I have (again, very abridged):
modelBuilder.Entity<Vehicle>(entity =>
{
entity.HasOne(dvlaRec => dvlaRec.dvlaDetail).WithMany().HasForeignKey(dvla => dvla.registrationNo);
});
This works fine when there is an associated record in the DVLA table, but that isn't always the case. I need to keep them as separate entities as my API will be required to return details from the DVLA table separately as well. Is there any way to create an optional foreign key, as clearly, what I am doing is wrong.
Friendly advice:
Primary key as a string is not a good practice because of performance issues when data table has lots of data in it.
It would be better if you create your model like this:
public class Vehicle
{
public long Id { get; set; }
public string RegistrationNo { get; set; }
public string Capacity { get; set; }
public string MaxGross { get; set; }
public List<VehicleDvlaDetail> VehicleDvlaDetails { get; set; }
}
public class VehicleDvlaDetail
{
public long? VehicleId { get; set; }
public int? Co2Emissions { get; set; }
public Vehicle Vehicle { get; set; }
}
Vehicle and VehicleDvlaDetail are now connected without additional code in OnModelCreating method and it is possible to fetch vehicles with details like this (this is assuming you have named properties in dbcontext Vehicles and VehicleDvlaDetails):
_dbContext.Vehicles.Include(x => x.VehicleDvlaDetails).ToList();
Also as foreign key VehicleId is nullable - this allows for vehicles not to have any dvla details.
Wow. I spent about 3 hours looking for the answer, just posted the question and came across this:
Create an optional foreign key using the fluid-API for Entity Framework 7
So simple...

Circular Reference with Include in .NET Core

I am using code like below in .NET core
.Include(p => p.Company).ThenInclude(p => p.Country).ToList();
My classes look like below,
public partial class Company
{
public Guid Id { get; set; }
public string Name { get; set; }
public virtual Country Country { get; set; }
}
public partial class Country
{
public Country()
{
Companies = new HashSet<Company>();
}
public Guid Id { get; set; }
public string Name { get; set; }
public string ShortCode { get; set; }
public virtual ICollection<Company> Companies { get; set; }
}
And I want only Company and then Country in side the company to be populated. But I am getting the Company inside the Country and then Country in those Companies and so on populated which is causing the response delayed.
I have already tried difference examples of Include on Google/StackOverFlow.
This isn't actually a problem. EF has what's called "object fix-up". Internally, it uses an object cache. When it builds entity instances for database query results, it adds those to the object cache, allowing it to then pull out those objects later, rather than issuing the same queries again.
Because of this object cache, if it already existing entity instances corresponding to a relationship, it will auto-fill that relationship from the object cache. It's not issuing a series of circular queries forever.

ASP.NET MVC Auto generate integer number

Good day, a really newbie developer here.
I Have a form and it have a entity of "QueueNumber" Can someone show me how to code so that when ever i save my form it generates automatically QueueNumber + the Prefix, btw my prefix entity is in another class
public class Queue
{
public int QueueId { get; set; }
[Required]
public string Name { get; set; }
public string QueueNumber
public int ServiceId { get; set; }
public Service Service { get; set; }
}
-
public class Service
{
public int ServiceId { get; set; }
[Display(Name = "Service Name")]
public string ServiceName { get; set; }
[Display(Name = "Service Letter")]
public string ServiceLetter { get; set; }
[Display(Name = "Status")]
public bool? Status { get; set; }
[Display(Name = "Assigned Location")]
public int? LocationId { get; set; }
public virtual Location Location { get; set; }
public virtual ICollection<Customer> Customer { get; set; }
}
Outcome in database :
1. A001
2. A002
3. A003
i just want to be able to generate a queue number automatically and when i save in data base its like A= Service Letter and 001=QueueNumber. Thankyou
If the QueueNumber needs to be persisted to the table, then I would set it up as a calculated column so that the database can manage computing it and updating it if the underlying fields change.
If it is just something that you want to represent in the UI then I would recommend having the view model calculate this.
The entity can calculate something like this with a [NotMapped] attribute. For example:
public class Queue
{
public int QueueId { get; set; }
[Required]
public string Name { get; set; }
[NotMapped]
public string QueueNumber
{
get { return string.Format("{0}{1:000}", Service?.ServiceLetter ?? "?", QueueId);
}
[ForeignKey("Service")]
public int ServiceId { get; set; }
public Service Service { get; set; }
}
The problem with this approach is that to be able to rely on your Queue to reveal a QueueNumber, the Queue must eager load the Service, or you enable lazy loading and risk that performance hit vs. having Service == #null and getting an exception or invalid QueueNumber result. In the above example, if the Service isn't eager loaded you will get back something like "?001".
I prefer to use ViewModels for a number of reasons including performance, security, and handling conditions like this more cleanly.
For example, given a QueueViewModel as such:
[Serializable]
public sealed class QueueViewModel
{
public int QueueId{ get; set; }
public string Name { get; set; }
public string ServiceName { get; set; }
public string ServiceLetter { get; set; }
public string QueueNumber
{
return string.Format("{0}{1:000}", ServiceLetter, QueueId);
}
}
Then when reading the data, we don't pass Entities to the view, we pass our view model...
var viewModel = context.Queues
.Where(x => x.QueueId == queueId)
.Select(x => new QueueViewModel
{
QueueId = x.QueueId,
Name = x.Name,
ServiceName = x.Service.Name,
ServiceLetter = x.Service.ServiceLetter
}).Single();
return viewModel;
The benefits of this approach:
We don't have to worry about eager/lazy loading. The query fetches everything needed, and our view model can compute anything needed from the data loaded. (Queries can compute values as well if you like, but be wary of limitations in that the query has to be able to go to SQL, so no user functions, etc.)
Performance is improved since the query only returns the data needed rather than entire entity graphs, and no rish of lazy load hits.
Security is improved, we expose no more data to the client than is expected/needed, and we don't open the door for "lazy" updates where entities are attached to a context and saved without proper validation.

EF Core - Identity field suddenly jumped by 1000 and not able to search with Id

I am having a problem with primary key/Id of one table in a project.
In this table, the Id suddenly jumped from 38 to 1039.
Now the real issue is, when i find the entity by 1039 it doesn't exists but finding it by 39 gives me the entity.
I am not sure about this behaviour and hence not able to find the solution.
My model
public class Domain : Entity
{
public string Name { get; set; }
public string Description { get; set; }
}
public abstract class Entity
{
public int Id { get; set; }
public DateTime InsertDate { get; set; }
public DateTime? UpdateDate { get; set; }
public DateTime? DeleteDate { get; set; }
public bool IsDeleted { get; set; }
}
Method is like this...
public async Task<Response> Delete(int id)
{
var domain = await DataContext.Domains.FindAsync(id);
if (domain == null)
{
return new Response(ResponseType.NotFound);
}
}
Can anyone please help ?
it depend from Database setting IDENTITY-CACHE.
Identity cache store some values of a identity columns in case of SQL CRASH during a transaction or similar.
To avoid gaps in an identity column, you need to set IDENTITY-CACHE to OFF running this command on a SQL query window:
ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE = OFF
GO
you will find more informations here:
https://social.technet.microsoft.com/wiki/contents/articles/40666.sql-server-2017-identity-cache-feature.aspx

ASP.NET - Editable form at runtime + storing info about it in database/SQL session state

I was wondering whether someone has another sources of info about modifiable forms at runtime + how to store them.
What I have:
I have 3 tables atm:
Users (1 to many) Raports (1 to many) ThrashType
Raport class:
public class Raport
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Raport()
{
ThrashType = new HashSet<ThrashType>();
//Raport = new HashSet<Raport>();
}
[Key]
public int raport_id { get; set; }
public string who_did { get; set; }
public string where_from { get; set; }
public DateTime creation_time { get; set; }
public DateTime last_modyfication { get; set; }
public virtual ICollection<ThrashType> ThrashType { get; set; }
public virtual AspNetUsers AspNetUsers { get; set; }
}
ThrashType class:
public class ThrashType
{
[Key]
public int Key { get; set; }
//public string Name { get; set; }
//or type from dictionary that has around 100 words
public int Quantity { get; set; }
//public string CreatorsName { get; set; }
public virtual Raport Raport { get; set; }
}
What I want:
create a form that user can modify (meaning appending another instances of ThrashType to a Raport which in turn will be assigned to certain User)
recreate form made by user from stored record (also with information about name, quantities and so on)
learn more about storing serialized data or mb inspiration for the database
get more articles or information sources that could provide help
What I've read:
http://www.codeproject.com/Articles/32545/Exploring-Session-in-ASP-Net#26
http://adventuresdotnet.blogspot.com/2009/06/aspnet-moving-session-out-of-process.html
ASP.NET MVC - Adding form elements at runtime with javascript
and many more but wish not to spam this place
What I don't know:
how to append next instances of ThrashType to Raport at runtime
after having the custom Raport (that has 1-many ThrashTypes) how to
store it:
(by how I mean "which way would be best")
a) in database (it will later be analized by a set of
queries I'll invent based on what client will say)
b) how to
store it in SQL session state
What I wanted to do:
At first I thought that I could store information from form as a string that could be read from alghoritm later (like "10101011101" and position would say what kind of word from dictionary it is), but still it lacks the quantities. Querying string database for quantities seems like overkill-crazy idea. I'm thinking about mixing session and database - session for recreation of dropped work and database for storing ready reports that could be analized. Anyway I need your opinion and inspiration because it's killing me softly.
Even an answer to 1 part of this problem would be of very much needed and appriecieted help.
Thanks!

Resources