Code First Object not properly instantiating - entity-framework-4.1

I have a class department inheriting from activeentity
public class ActiveEntity : Entity, IActive
{
public ActiveEntity()
{
IsActive = true;
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
public bool IsActive { get; set; }
[Timestamp, ScaffoldColumn(false), DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Computed)]
public Byte[] Timestamp { get; set; }
[ScaffoldColumn(false)]
public string CreationUserId { get; set; }
[ScaffoldColumn(false)]
public string LastModifiedUserId { get; set; }
}
public class Department:ActiveEntity
{
public Department()
{
this.Address = new DepartmentAddress();
}
[StringLength(9),MinLength(9),MaxLength(9)]
public string Name { get; set; }
public Guid ManagerId { get; set; }
[UIHint("AjaxDropdown")]
public User Manager { get; set; }
public Guid? AddressId { get; set; }
public DepartmentAddress Address { get; set; }
public ICollection<OverheadRate> OverheadRates { get; set; }
}
I am just using annotations no Fluent API. The data saves to the data Sql Server 2008 just fine however the address object never gets instantiated, even though I have the context use the include
return c.Set<Department>().Include(d => d.Address).Include(d => d.Manager).Where(predicate);
The data is returned I run sql profiler and then run the query it returns the correct data.
Any thoughts or suggestions?

Remove instantiating the address (this.Address = new DepartmentAddress();) in the Department constructor. Instantiating navigation references in the default constructor is evil and has nasty side effects like these:
What would cause the Entity Framework to save an unloaded (but lazy loadable) reference over existing data?
EF 4.1 Code First: Why is EF not setting this navigation property?

Related

How to make a POST request with postman?

I have two models, Sever and Update. The ralationship between these two classes is 1...*N, meaning that each Server has multiple updates.
Here is my Server model:
public class Server
{
public Server()
{
UpdateList = new HashSet<Update>();
}
[Key]
[Required]
public int ID { get; set; }
[Required]
public string ComputerName { get; set; }
[Required]
public string Type { get; set; }
[Required]
public string Estado { get; set; }
[Required]
public string Phase { get; set; }
public virtual ICollection<Update> UpdateList { get; set; }
}
Here is my Update model:
public class Update
{
[Required]
public int ID { get; set; }
public string updateId { get; set; }
public string updateTitle { get; set; }
public string updateDescription { get; set; }
[System.ComponentModel.DataAnnotations.Schema.ForeignKey("Server")]
[Display(Name = "Server")]
public int? ServerFK { get; set; }
public virtual Server Server { get; set; }
}
Here is the POST request that I'm using in postman:
{
"computerName":"ServerTestUpdate",
"type":"ServidorAplicacional",
"estado":"Reboot Pending",
"phase":"0",
"updateList":
[{
"updateId":"idTest",
"updateTitle":"Update1",
"updateDescription":"TestDescription"
}]
}
However, when I do this, I get the following error:
System.Text.Json.JsonException: A possible object cycle was detected.
This can either be due to a cycle or if the object depth is larger
than the maximum allowed depth of 32. Consider using
ReferenceHandler.Preserve on JsonSerializerOptions to support cycles.
Is there something wrong with the syntax or maybe is something in the controller?
Thank you in advance
Most likely this is a problem in serializing the object, since deserialization wouldn’t care about cycles. It’s probably the fact that your Server object has a collection of Updates, all of which have a Server property pointing back and this causes a cycle.
If you add JsonIgnore attribute to the property this should go away (from System.Text.Json.Serialization namespace)
[JsonIgnore]
public virtual Server Server { get; set; }

REST API returns "bad array" instead of JSON object

I'm building REST API server in .NET core. I'm testing my code via Postman software. I have a problem with Include() method that enables me to attach navigation property data. I'm trying to get data in [HttpGet] action and objects that are being returned are wrong.
My code :
MODELS
Session model
public class Session
{
[Key]
public int IDSession { get; set; }
[Required]
public DateTime LogInTime { get; set; }
public DateTime LogOutTime { get; set; }
[Required]
public int IDUser { get; set; }
public User User { get; set; }
[Required]
public int IDMachine { get; set; }
public Machine Machine { get; set; }
}
User model
public class User
{
[Key]
public int IDUser { get; set; }
[Required]
public string Forename { get; set; }
[Required]
public string Name { get; set; }
public string AvatarPath { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public string Password { get; set; }
public User CreatedBy { get; set; }
public DateTime CreatedAt { get; set; }
public List<UserGroup> UsersGroups { get; set; }
public List<Alarm> ExecutedAlarms { get; set; }
public List<Alarm> ResetedAlarms { get; set; }
public List<AccessCard> Cards { get; set; }
public List<AccessCard> UserCardsAdded { get; set; }
public List<User> UsersAdded { get; set; }
public List<Session> Sessions { get; set; }
public List<EventsLog> Events { get; set; }
public List<Reference> References { get; set; }
public List<UserPermission> UsersPermissions { get; set; }
}
Session controller
[Produces("application/json")]
[Route("api/Sessions")]
public class SessionsController : Controller
{
private readonly DBContext _context;
#region CONSTRUCTOR
public SessionsController(DBContext context)
{
_context = context;
}
#endregion
#region HTTP GET
// GET: api/sessions
[HttpGet]
public async Task<IActionResult> GetSessions()
{
var sessions = await _context.Sessions.Include(s => s.User). ToListAsync();
if (sessions.Any())
{
return new ObjectResult(sessions);
}
else
{
return NotFound();
}
}
// GET: api/sessions/1
[HttpGet("{id}", Name = "GetSessionByID")]
public async Task<IActionResult> GetSessionByID(Int32 id)
{
var session = await _context.Sessions.Include(s => s.User).FirstOrDefaultAsync(s => s.IDSession == id);
if (session == null)
{
return NotFound();
}
else
{
return new ObjectResult(session);
}
}
#endregion
}
The idea is that User model contains List<Session> collection that he/she created. I want to be able to return users with its sessions
Of course Session model contains a single User because every session is related with a specific, single User.
Now, when I need to get all sessions objects in SessionController with GetSessions() or GetSessionsByID() I use POSTMAN [HttpGet] action like this : http://localhost:8080/api/sessions which returns me wrong data :
A session contains a user and in turn a single user is related with its sessions. It looks like it tries to return me Session object properly, includes User object but then it tries to include all sessions for that User. That's not what I want. It looks like some kind of a loop. Sessions shoud be returned with its User objects and that's it. How can I achieve that ? Am I doing some logical mistake in my models ?
Thanks !
I met also this issue recently. So, I've fixed it by adding this script in the Startup.cs file and ConfigureServices method :
services.AddMvc().AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
So, you suffix services.AddMvc() by this code who means that you have to make JSON.Net to ignore cycles finded to the nested object request. And of course having Newtonsoft.Json package installed to your project and referenced in each concerned file
For much clearer information, see this link at Related Data and Serialization section :
https://learn.microsoft.com/en-us/ef/core/querying/related-data
Hope this is helpfull for you

How to add to a collection in Entity Framework 4.1

I'm trying to add an object to an IList entity but the runtime throws a 'Object reference not set to an instance of an object.' exception.
Here is my model:
public class Discussion
{
[Key]
public int DiscussionId { get; set; }
public string Title { get; set; }
public virtual List<Message> Messages { get; set; }
public virtual List<Tag> Tags { get; set; }
public Guid Guid { get; set; }
public string UrlTitle { get; set; }
}
and here is the problematic line:
newDiscussion.Messages.Add(newMessage);
Apparently newDiscussion.Messages is null. What am I doing wrong?
Mark
You should initialize any collections inside of the class's constructor.
public class Discussion
{
public Discussion()
{
Messages = new List<Message>();
Tags = new List<Tag>();
}
// ...
}

Self referencing loop detected serialization exception

This is my class:
public partial class Event
{
public Event()
{
this.Comments = new HashSet<Comment>();
this.Rates = new HashSet<Rate>();
this.RawDates = new HashSet<RawDate>();
}
public int ID { get; set; }
public string Title { get; set; }
public string Summary { get; set; }
public string SiteURL { get; set; }
public string ContactEmail { get; set; }
public string LogoURL { get; set; }
public int EventType_ID { get; set; }
public Nullable<int> Location_ID { get; set; }
public Nullable<System.DateTime> BegginingDate { get; set; }
public string nTrain { get; set; }
public string Content { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual Conference Conference { get; set; }
public virtual ICollection<Rate> Rates { get; set; }
public virtual ICollection<RawDate> RawDates { get; set; }
public virtual EventType EventType { get; set; }
public virtual Location Location { get; set; }
}
When I call web api post method, exception mentioned in the title is thrown in this line:
var response = await client.PostAsJsonAsync("api/event", event);
I added [JsonIgnore] above every virtual field in Event class. This time serialization worked, but ignored fields were not serialized, their value is null. I really need all information contained in Event object. How can I solve this problem?
Adding below configuration in WebAPIConfig.cs resolves the bug.
var json = config.Formatters.JsonFormatter;
//Below configuration to mandatory to resolve the Self referencing loop detected with
"Newtonsoft.Json.JsonSerializationException" ,
json.SerializerSettings.PreserveReferencesHandling =
Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
Circular referencing objects cannot be JSON serialized. I would recommend you using a view model in which you will include the properties you need and then have your action return this view model instead of the actual domain model.

Mapping complex tree object using fluent mappings in EF 4.1?

I need some assistance with how to properly mapping this structure in EF 4.1:
public class Menu: Entity
{
public string Title { get; set; }
public virtual ICollection<MenuItem> MenuItems { get; set; }
}
public class MenuItem: Entity
{
public string Icon { get; set; }
public string Text { get; set; }
public string Action { get; set; }
public string Controller { get; set; }
public string Parameters { get; set; }
public virtual MenuItemType Type { get; set; }
public virtual Guid? ContextMenuId { get; set; }
public virtual Menu ContextMenu { get; set; }
public virtual Guid? ParentMenuItemId { get; set; }
public virtual MenuItem ParentMenuItem { get; set; }
public virtual ICollection<MenuItem> ChildMenuItems { get; set; }
}
The Entity base class has the ID for the enitties and I also have a base mapping class that builds the mappings for the key. Here is what I have so far for the MenuItem class:
public class MenuItemMapping : EntityConfiguration<MenuItem>
{
public MenuItemMapping()
{
HasOptional(mi => mi.ParentMenuItem).WithMany(p => p.ChildMenuItems).HasForeignKey(mi => mi.ParentMenuItemId).WillCascadeOnDelete(false);
HasOptional(mi => mi.ContextMenu).WithMany().HasForeignKey(mi => mi.ContextMenuId).WillCascadeOnDelete(false);
}
}
My concern is in the ContextMenu because it is a Menu type and not sure the best way to handle this type o mapping.
Update
Well, I added an additional mapping for the Menu (in a MenuMapping class similar to the above mapping class) for the collection of Menuitems and it seems to be OK, but I'd still like to know if what I am doing is correct.
Apparently, my mappings were fine. I thought I would have issues with circular references.