Entity Framework/WebApi unable to retrieve associated results - asp.net

I am trying to retrieve data as XML using Entity Framework and WebAPI.
All I get is an empty Child container, I have populated two records in OrderItem with OrderId=1 yet still nothing, see <OrderItems/> below:
<ArrayOfOrder xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/WebApplication6.Models">
<Order>
<ID>1</ID>
<OrderItems/>
<Username>Test</Username>
</Order>
</ArrayOfOrder>
My Order model is as follows:
public class Order
{
public Order()
{
this.OrderItems = new HashSet<OrderItem>();
}
public int Id { get; set; }
public string Username { get; set; }
public ICollection<OrderItem> OrderItems { get; set; }
}
My OrderItems model is as follows:
public class OrderItem
{
public int Id { get; set; }
public int OrderId { get; set; }
public int Qty { get; set; }
public Order Order { get; set; }
}
Controller code for GetOrders:
// GET api/Order
public IQueryable<Order> GetOrders()
{
return db.Orders;
}
I am just trying to learn entity framework and WebApi, this part seems to be basic functionality and I can't find any solid reference to this at a basic level. Can anyone explain what I am missing?

After hours of searching I found the solution. Basically I needed to include the sub-dataset. This is done in the controller function:
public IQueryable<Order> GetOrders()
{
return db.Orders.Include(p => p.OrderItems);
}
However this introduces the error:
Object graph for type
'System.Collections.Generic.HashSet`1[[WebApplication7.Models.OrderItem,
WebApplication7, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null]]' contains cycles and cannot be serialized if
reference tracking is disabled.
Which is fixed for XML by using Datacontracts
Updated OrderItem model:
using System.Runtime.Serialization;
[DataContract]
public class OrderItem
{
[DataMember]
public int Id { get; set; }
[DataMember]
public int OrderId { get; set; }
[DataMember]
public int Qty { get; set; }
public Order Order { get; set; }
}
Note there is no [DataMember] annotation before Order
Now my result is as expected:
<ArrayOfOrder xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/WebApplication7.Models">
<Order>
<Id>1</Id>
<OrderItems>
<OrderItem>
<Id>2</Id>
<OrderId>1</OrderId>
<Qty>231</Qty>
</OrderItem>
<OrderItem>
<Id>4</Id>
<OrderId>1</OrderId>
<Qty>2314</Qty>
</OrderItem>
</OrderItems>
<Username>first</Username>
</Order>
</ArrayOfOrder>

Related

Establishing one to one relations with Entity Framework 7

Having the following parent class:
[Table("smart_recharge_registro")]
public class SmartRechargeRegistro
{
[Key]
public int id { get; set; }
public SmartRechargeRequest request { get; set; }
public SmartRechargeProceso proceso { get; set; }
public SmartRechargeResponse response { get; set; }
}
Which in turn references the following child classes:
[Table("smart_recharge_request")]
public class SmartRechargeRequest
{
public String nombreDeUsuario { get; set; }
public String passwordDeUsuario { get; set; }
public String msisdnSuscriptor { get; set; }
}
and:
[Table("smart_recharge_proceso")]
public class SmartRechargeProceso
{
[Key]
public int id { get; set; }
public String carrierId { get; set; }
public String cliente { get; set; }
public String network { get; set; }
}
and lastly:
[Table("smart_recharge_response")]
public class SmartRechargeResponse
{
public Boolean responseSuccess { get; set; }
public int responseCode { get; set; }
public String? responseDetails { get; set; }
}
The Add-Migration and Update-Database command execute without problems. However, when I try to save
await _repository.RegistroColeccion.AddAsync(registro);
await _repositorio.SaveChangesAsync();
I get the following error:
Microsoft.EntityFrameworkCore.DbUpdateException: Could not save changes. Please configure your entity type accordingly.
---> MySql.Data.MySqlClient.MySqlException (0x80004005): Cannot add
or update a child row: a foreign key constraint fails
(beservicebroker_dev.registro_eventos_srdotnet, CONSTRAINT
FK_registro_eventos_srdotnet_SmartRechargeProceso_procesoid FOREIGN
KEY (procesoid) REFERENCES smartrechargeproceso (id) O)
To solve the problem, I tried to create one-to-one relationships following this tutorial
modelBuilder.Entity<SmartRechargeRegistro>()
.HasOne(s => s.request)
.WithOne(r => r.SmartRechargeRegistro)
.HasForeignKey<SmartRechargeRequest>(r => r.id);
modelBuilder.Entity<SmartRechargeRegistro>()
.HasOne(s => s.proceso)
.WithOne(p => p.SmartRechargeRegistro)
.HasForeignKey<SmartRechargeProceso>(p => p.id);
modelBuilder.Entity<SmartRechargeRegistro>()
.HasOne(s => s.response)
.WithOne(r => r.SmartRechargeRegistro)
.HasForeignKey<SmartRechargeResponse>(r => r.id);
Inside SmartRechargeRequest, SmartRechargeProceso and SmartRechargeResponse, added the following:
[JsonIgnore]
public SmartRechargeRegistro SmartRechargeRegistro { get; set; }
Also added inside SmartRechargeRequest and SmartRechargeResponse an id
[Key]
public int id { get; set; }
I'm still unable to test the endpoint because the SmartRechargeRequest and SmartRechargeResponse are completely disfigured in the swagger (even if the [JsonIgnore] or [IgnoreDataMember] annotations are set) due to the presence of that SmartRechargeRegistro object.
I'm pretty sure my solution is misguided and I'm getting the process completely wrong.
What would be the proper way to map one-to-one relationships for this case? Any help will be appreciated.
Please note that in reality, these classes are huge (dozens of properties), so it's not possible to merge all of them on a single table.

JsonConvert.DeserializeObject<> is returning null last childtoken of the two childrentokens

I am sending a JObject from the frontend to my API, which is divided into First and Last childtokens, as seen in the picture below:
However, when I am trying to use the following code, the last part of childrendtoken is becoming null
var RVoucher = JsonConvert.DeserializeObject<VMReceive>(request.ToString());
This is what I am having in the debugging mode:
Here, the VMReceive is a viewModel that consists of another viewmodel "VMMonth"and an ado.net generated model class "ReceiveVoucher".
Code of the models are given below:
public class VMReceive
{
public List<VMMonth> Month { get; set; }
public ReceiveVoucher receiveVoucher { get; set; }
}
public class VMMonth
{
public int item_id { get; set; }
public string item_text { get; set; }
}
public partial class ReceiveVoucher
{
public int ReceiveVoucherId { get; set; }
public Nullable<int> MonthId { get; set; }
public string ReceivedBy { get; set; }
public string Remarks { get; set; }
public Nullable<int> ReceivedAmount { get; set; }
}
I have also tried putting [JsonProperty("")] over each property of my "ReceiveVoucher" model class, but got the same 'null' issue.
I am not sure about what I am doing wrong here, your suggestion regarding this will be very helpful.
Your JSON property name doesn't match. Your class uses receiveVoucher whereas the JSON is ReceiveAmount. Also, why are you using JObject in the first place, this should work by just using the class name as the action parameter:
public HttpResponse PostReceive([FromBody] VMReceive RVoucher, int userId)
{
...
}

How to fix ‘Cannot create a DbSet for 'DM_NCC_ThueSuat' because this type is not included in the model for the context’ error in C# ASP.NET

I have a code block regards get a list like that in aspnetzero:
public async Task<List<DMNCCThueSuatDto>> GetDSThueSuat()
{
using (_unitOfWorkManager.Current.SetTenantId(null))
{
var lstthueSuat = await _dmThueSuatRepository.Query(t => t.Where(i =>
i.IsDeleted == false)).OrderBy("thuesuat_ma asc").ToListAsync();
return ObjectMapper.Map<List<DMNCCThueSuatDto>>(lstthueSuat);
}
}
I expected a list of DMNCCThueSuatDto is returned but the error
Cannot create a DbSet for 'DM_NCC_ThueSuat' because this type is not
included in the model for the context.
is always displayed.
Also, i had myown a declaration
public virtual DbSet DS_ThueSuat { get; set; }
in my DBContext.
In my mariadb database, i had a table called "vs_dm_ncc_thuesuat"
and i have already declare a class for mapping to the table above
namespace VS.vHoaDon.Domains.DanhMuc.DMNhaCungCap
{
[Table("vs_dm_ncc_thuesuat")]
[MultiTenancySide(MultiTenancySides.Host)]
public class DM_NCC_ThueSuat : FullAuditedEntity
{
public int ThueSuat_Ma { get; set; }
public string ThueSuat_Ten { get; set; }
public int ThueSuat_GiaTri { get; set; }
public bool ThueSuat_HieuLuc { get; set; }
public DateTime? ThueSuat_BatDau { get; set; }
public DateTime? ThueSuat_KetThuc { get; set; }
}
}
I don't know why?
Any helps is appreciated.
Thank you so much.

How to extend table with a view in Entity framework

I wanted to have a view to add a few extra proprieties and I tried the following:
Base table:
namespace Core.Model {
public class Item
{
[Key]
public int ItemId { get; set; }
[Required]
public ItemType Type { get; set; }
[Required]
[MaxLength(255)]
public string Name { get; set; }
//...
}
}
extended view:
namespace Core.Model
{
public class ItemExtended : Item
{
public int? CommentsCount { get; set; }
}
}
Then in the Context I have:
public DbSet<QuiverItemExtended> ItemsExtended { get; set; }
modelBuilder.Entity<ItemExtended>()
.ToTable("ItemsExtended")
.HasKey(view => new { view.ItemId });
This works for querying but when I try to insert a normal Item I get this exception:
All objects in the EntitySet 'Context.Items' must have unique primary
keys. However, an instance of type 'Core.Model.ItemExtended' and an
instance of type 'Core.Model.Item' both have the same primary key
value, 'EntitySet=Items;ItemId=1097'.
Any ideias how I can fix this?
thanks in advance
In this case I will solve this using a calculated column: http://www.davepaquette.com/archive/2012/09/23/calculated-columns-in-entity-framework-code-first-migrations.aspx

Using ComplexType with ToList causes InvalidOperationException

I have this model
namespace ProjectTimer.Models
{
public class TimerContext : DbContext
{
public TimerContext()
: base("DefaultConnection")
{
}
public DbSet<Project> Projects { get; set; }
public DbSet<ProjectTimeSpan> TimeSpans { get; set; }
}
public class DomainBase
{
[Key]
public int Id { get; set; }
}
public class Project : DomainBase
{
public UserProfile User { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public IList<ProjectTimeSpan> TimeSpans { get; set; }
}
[ComplexType]
public class ProjectTimeSpan
{
public DateTime TimeStart { get; set; }
public DateTime TimeEnd { get; set; }
public bool Active { get; set; }
}
}
When I try to use this action I get the exception The type 'ProjectTimer.Models.ProjectTimeSpan' has already been configured as an entity type. It cannot be reconfigured as a complex type.
public ActionResult Index()
{
using (var db = new TimerContext())
{
return View(db.Projects.ToList);
}
}
The view is using the model #model IList<ProjectTimer.Models.Project>
Can any one shine some light as to why this would be happening?
Your IList<ProjectTimeSpan> property is not supported by EF. A complex type must always be part of another entity type, you cannot use a complex type by itself. If you absolutely need to have ProjectTimeSpan as a complex type, you will need to create a dummy entity type that only contains a key and a ProjectTimeSpan, and change the type of Project.TimeSpans to a list of that new type.

Resources