Odata $expand of property returns null - entity-framework

I'm trying to get properties of an object through my odata WCF service, but when i use $expand on a particular property, it appears to be "null". However, in another property I have the Id of that object (using Entityframework) and there you can see the Id is NOT empty.
The Model:
[Table("Approval"), DataContract, IgnoreProperties("Status", "Id")]
public class Approval : BaseEntity
{
...
[DataMember]
public Guid? ApproverId { get; set; }
[DataMember, ForeignKey("ApproverId")]
public virtual User Approver { get; set; }
[DataMember]
public virtual Request Request { get; set; }
}
[Table("Request"), DataContract, DataServiceKey("Id")]
public class Request : BaseEntity
{
...
[DataMember]
public Guid? LastModifiedById { get; set; }
[DataMember, ForeignKey("LastModifiedById")]
public virtual User LastModifiedBy { get; set; }
[DataMember]
public virtual Approval Approval { get; set; }
[DataMember, Required]
public Guid AbsenteeId { get; set; }
[DataMember, ForeignKey("AbsenteeId")]
public virtual User Absentee { get; set; }
[DataMember, Required]
public Guid AbsenceTypeId { get; set; }
[DataMember, ForeignKey("AbsenceTypeId")]
public virtual AbsenceType AbsenceType { get; set; }
}
The odata service call:
http://<servername>/DataService.svc/Approvals?&$format=json&$expand=Request,Request/Absentee,Request/LastModifiedBy,Request/AbsenceType,Approver&$skip=0&$top=1
The Returned Result:
{
"odata.metadata": "http://<servername>/DataService.svc/$metadata#Approvals",
"value": [
{
"Approver": null,
"Request": {
"LastModifiedBy": null,
"Absentee": null,
"AbsenceType": null,
...
"LastModifiedById": "6a1f8e79-99f5-e511-9444-0050568627d2",
"AbsenteeId": "6a1f8e79-99f5-e511-9444-0050568627d2",
"AbsenceTypeId": "fc7e8a5d-99f5-e511-9444-0050568627d2"
},
...
"ApproverId": null
}
]
}
In this case, value -> Request -> LastModifiedBy/Absentee/AbsenceType should NOT be empty!!!!
Anyone who knows what I missed/did wrong?

Related

EF Core 7 - error occurred: the entity type 'List<string>' requires a primary key to be defined

I get an error when I use EF Core 7 to create entities.
The entity type 'List' requires a primary key to be defined. If you intended to use a keyless entity type, call 'HasNoKey' in 'OnModelCreating'. For more information on keyless entity types, see https://go.microsoft.com/fwlink/?linkid=2141943.
I have found the error prop, that's Project of service entity, when I only annotate Project of service entity, then I can run Add-Migration successfully. I don't know why and I also don't know how to fix this error.
Does somebody know this error? Please help...
public class Service : EntityBase
{
public Guid? DefaultCapacityUnitId { get; set; }
public Guid? DefaultSizeUnitId { get; set; }
public virtual SizeUnit DefaultSizeUnit { get; set; }
public Guid ProjectId { get; set; }
public Project Project { get; set; }
public Guid? ParentId { get; set; }
public virtual Service Parent { get; set; }
public Guid DisciplineId { get; set; }
public virtual Discipline Discipline { get; set; }
public virtual List<Service> SubServices { get; set; } = new List<Service>();
}
public class Equipment : EntityBase
{
public Guid ProjectId { get; set; }
public Project Project { get; set; }
public Guid? ServiceId { get; set; }
public virtual Service Service { get; set; }
public Guid DisciplineId { get; set; }
public virtual Discipline Discipline { get; set; }
}
public abstract class EntityBase
{
[Key]
public virtual Guid Id { get; set; } = Guid.NewGuid();
private string name;
[Required, MaxLength(200)]
public virtual string Name
{
get
{
return name?.Trim();
}
set
{
name = value?.Trim();
}
}
private string shortName;
[Required, MaxLength(100)]
public virtual string ShortName
{
get
{
return shortName?.Trim();
}
set
{
shortName = value?.Trim();
}
}
[NotMapped]
public EntityBase Snapshot { get; set; }
[NotMapped]
public List<string> ValueChangedProperties { get; set; } = new List<string>();
}
public class Project : EntityBase
{
}
public class Discipline : EntityBase
{
public Guid ProjectId { get; set; }
public virtual Project Project { get; set; }
public virtual List<Service> Services { get; set; } = new List<Service>();
public Guid? ScenarioId { get; set; }
public Guid? ParentId { get; set; }
public virtual Discipline Parent { get; set; }
}
public partial class TestDbContext : DbContext
{
public TestDbContext(DbContextOptions<TestDbContext> options)
: base(options)
{ }
public TestDbContext()
{
}
public DbSet<Project> Projects { get; set; }
public DbSet<Discipline> Disciplines { get; set; }
public DbSet<Service> Services { get; set; }
public DbSet<ServiceGroup> ServiceGroups { get; set; }
public DbSet<SizeUnit> SizeUnits { get; set; }
public DbSet<Equipment> Equipments { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var entityTypes = typeof(TestDbContext).GetProperties()
.Where(p => p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>))
.Select(p => p.PropertyType.GetGenericArguments()[0]).ToList();
entityTypes.ForEach(entityType => {
var entityName = entityType.Name;
modelBuilder.Entity(entityType).ToTable(entityName);
});
modelBuilder.Entity<ServiceMapping>().HasOne(x => x.Service).WithMany().HasForeignKey(x => x.ServiceId).OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<ServiceMapping>().HasOne(x => x.TargetService).WithMany().HasForeignKey(x => x.TargetServiceId).OnDelete(DeleteBehavior.Cascade);
base.OnModelCreating(modelBuilder);
}
}
public class ServiceGroup : EntityBase
{
public Guid ProjectId { get; set; }
public virtual Project Project { get; set; }
public Guid? ScenarioId { get; set; }
}
public class ServiceMapping : EntityBase
{
public Guid ProjectId { get; set; }
public virtual Project Project { get; set; }
public Guid ServiceId { get; set; }
public virtual Service Service { get; set; }
public Guid TargetServiceId { get; set; }
public virtual Service TargetService { get; set; }
}
public class SizeUnit : EntityBase
{
public Guid ProjectId { get; set; }
public virtual Project Project { get; set; }
public int UnitType { get; set; }
}
If I annotate Project of service entity, then it's all right.

How to fix "Exception: Invalid channel" error in my API

I'm trying to save a object Using HTTP Post Method in my API Controller, but it's returning a error, i've tried to do the same in another controler and it works. I hope you may help!
The Request that I tried:
{
"integrationServiceHost": "10.80.80.10",
"RouterHost": "10.80.80.10",
"Enabled": "false",
"IntegrationServiceRemotePort": "1234",
"RouterSocketPort":"1234",
"RouterRemotePort":"1234",
"IDChannelBehavior":"10",
"IDEPS":"1",
"Description":"Teste Whats",
"IDChannel":"0"
}
ChannelWhatsapp Class:
public class ChannelWhatsApp : Channel
{
public ChannelWhatsApp();
[Column("WHATSAPP_UserName")]
public string UserName { get; set; }
[Column("WHATSAPP_Password")]
public string Password { get; set; }
[Column("WHATSAPP_DisplayName")]
public string DisplayName { get; set; }
}
url : http://172.19.22.81:5000/api/channelWhatsapp/saveDto
Channel Class :
public abstract class Channel : NotifyPropertyChanged
{
public Channel();
public virtual ICollection<Interaction> Interaction { get; set; }
public virtual ICollection<Schedule> Schedule { get; set; }
public virtual ICollection<Queue> Queue { get; set; }
public virtual ICollection<Session> Session { get; set; }
public virtual ChannelBehavior ChannelBehavior { get; set; }
public virtual EPS EPS { get; set; }
public DateTime? DtLastChange { get; set; }
[MaxLength(100)]
public string IntegrationServiceHost { get; set; }
[MaxLength(100)]
public string RouterHost { get; set; }
public bool Enabled { get; set; }
public int? IntegrationServiceRemotePort { get; set; }
public int? RouterSocketPort { get; set; }
public int? RouterRemotePort { get; set; }
[ForeignKey("ChannelBehavior")]
public int IDChannelBehavior { get; set; }
[ForeignKey("EPS")]
public int IDEPS { get; set; }
[MaxLength(200)]
public string Description { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int IDChannel { get; set; }
[NotMapped]
public string IconName { get; set; }
[NotMapped]
public byte? PendingPauseCode { get; set; }
[NotMapped]
public bool IsPausePending { get; set; }
[NotMapped]
public SystemUserOperator Operator { get; set; }
[NotMapped]
public DateTime StateMomment { get; set; }
[NotMapped]
public UserStateType CurrentState { get; set; }
public virtual ICollection<ChannelSkill> ChannelSkills { get; set; }
[NotMapped]
public ChannelTypeType Type { get; set; }
}
My Controller:
[Route("api/ChannelWhatsapp/{Action}")]
[ApiController]
public class ChannelWhatsappController : IrideController<ChannelWhatsApp>
{
public ChannelWhatsappController(IrideContext context) : base(context) { }
[HttpPost("")]
[ActionName("saveDto")]
public IActionResult saveDto([FromBody] ChannelWhatsApp entity)
{
try
{
////Obtem o data
//entity.DtLastChange = IrideUtil.getDate() ;
//_context.Set<ChannelWhatsApp>().Update(entity);
//_context.SaveChanges();
return Ok(entity);
}
catch (Exception ex)
{
return Ok(ex.ToString());
}
}
}
returned error:
Exception: Invalid channel IrideCM.Model.Channel..ctor()
IrideCM.Model.ChannelWhatsApp..ctor() lambda_method(Closure )
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader
reader, JsonObjectContract objectContract, JsonProperty
containerMember, JsonProperty containerProperty, string id, out bool
createdFromNonDefaultCreator) in JsonSerializerInternalReader.cs
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader
reader, Type objectType, JsonContract contract, JsonProperty member,
JsonContainerContract containerContract, JsonProperty containerMember,
object existingValue) in JsonSerializerInternalReader.cs
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader
reader, Type objectType, bool checkAdditionalContent) in
JsonSerializerInternalReader.cs
When posting a payload to a controller in the request's body, you need to make sure the payload's structure matchs the structure of the expected class.
In your case, it does not match at all. You just need to post a payload with the same type as the type expected in the FromBody param of your endpoint.

c# repository ICollection navigation error

I am stuck and need help.
Checking user permission in a controller methods as below
if (User.IsInRole("CanAccessOnlyOwnDepartmentRequest"))
{
//CanAccessOnlyOwnDepartmentRequest yetkisinie sahipse
itemResult = await Repository.PaginatedListDescAsync(p => p.BranchAsset.BranchId == userBranchId &&
(p.AssigningUser.Employee.DepartmentId == branchUser.DataResult.Employee.DepartmentId ||
p.AssignedUser.Employee.DepartmentId == branchUser.DataResult.Employee.DepartmentId) &&
(p.Assignments.LastOrDefault().AssignUser.Employee.DepartmentId == branchUser.DataResult.Employee.DepartmentId),
p => p.Id, paging.PageIndex, paging.PageSize,GetNavigation:true);
}
what I am trying to do is that I want to check Request -> Assignments collections last item's assign user and assigned user Department ID whether is equal to the user who requested the result.
this is my request entity definitions of Assessments part
private ICollection<RequestAssignment> _assignments;
public virtual ICollection<RequestAssignment> Assignments
{
get => LazyLoader?.Load(this, ref _assignments);
set => _assignments = value;
}
I am using EF Core 2.1 and LazyLoading on the necessary entity property
the error I am facing:
Property 'System.Guid DepartmentId' is not defined for type 'System.Collections.Generic.IAsyncEnumerable`1[Q.Entity.Corporate.EmployeeEntity.Employee]'
Parameter name: property
EDİT :
Request Class
public Guid? BranchAssetId { get; set; }
public BranchAsset BranchAsset { get; set; }
public Guid AssigningUserId { get; set; }
public BranchUser AssigningUser { get; set; }
public Guid AssignedUserId { get; set; }
public BranchUser AssignedUser { get; set; }
public Guid StateTypeId { get; set; }
public RequestStateType StateType { get; set; }
public Ticket Ticket { get; set; }
public ICollection<RequestFeedback> Feedbacks { get; set; }
public ICollection<RequestState> States { get; set; }
public ICollection<RequestProcess> Process { get; set; }
public ICollection<RequestMessage> Messages { get; set; }
public ICollection<RequestAssignment> Assignments { get; set; }
RequestAssignment Class :
public Guid RequestId { get; set; }
public Request Request { get; set; }
public Guid AssignUserId { get; set; }
public BranchUser AssignUser{ get; set; }
public Guid AssignedUserId { get; set; }
public BranchUser AssignedUser{ get; set; }
public string Note { get; set; }
BranchUser Class:
public Guid EmployeeId { get; set; }
public Employee Employee{ get; set; }
public Guid BranchId { get; set; }
public Branch Branch { get; set; }
public Guid? ApplicationUserId { get; set; }
public ApplicationUser ApplicationUser { get; set; }
public ICollection<BranchUserRequestApproval> RequestApprovals { get; set; }
Employee Class
public Guid DepartmentId { get; set; }
public Department Department { get; set; }
public Person PersonInformation { get; set; }
public Guid BranchId { get; set; }
public Branch Branch { get; set; }

Entity framework issue- The principal end of this association must be explicitly configured

Hi I am using CodeFirst approach to create database but I am getting below error
The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.
The entities are following
public abstract class EntityBase
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public DateTime CreationDate { get; set; }
public DateTime ModifiedDate { get; set; }
public int CreatedByUserId { get; set; }
public int ModifiedByUserId { get; set; }
[ForeignKey("CreatedByUserId")]
public virtual User CreatedBy { get; set; }
[ForeignKey("ModifiedByUserId")]
public virtual User ModifiedBy { get; set; }
public bool IsActive { get; set; }
}
public class User : EntityBase
{
public string UserName { get; set; }
public string DisplayName { get; set; }
public string Password { get; set; }
}
Please help me.
Thanks
Vinod

Nested object null on client side in CODE FIRST EF RIA Service

I have nested object in EF Code First using Silverlight RIA service, I am able to get the data at service side but when I see it on client side child objects are null. Could you please guide me what's wrong.
[HasSelfValidation]
public class Batch
{
public int BatchId { get; set; }
public string BatchName { get; set; }
[Include]
[Composition]
[Association("FK_Batch_BathSetItemSet", "BatchId", "BatchSetIdItemSetId")]
public virtual ICollection<BatchSetItemSet> BatchSetItemSets { get; set; }
}
public class BatchSetItemSet
{
public int BatchSetIdItemSetId { get; set; }
public int BatchId { get; set; }
public Nullable<int> ItemSetId { get; set; }
public string CreatedBy { get; set; }
public Batch Batch { get; set; }
[Include]
[Composition]
[Association("FK_BathSetItemSet_ItemSet", "BatchSetIdItemSetId", "ItemSetId")]
public ItemSet ItemSet { get; set; }
}
public class ItemSet
{
public int ItemSetId { get; set; }
public int CustodianId { get; set; }
public string ItemSetName { get; set; }
public virtual ICollection<BatchSetItemSet> BatchSetItemSets { get; set; }
[Include]
[Composition]
[Association("FK_ItemSet_Custodian", "ItemSetId", "CustodianId")]
public virtual Custodian Custodian { get; set; }
}
and service call is : this.DbContext.Batches.Include("BatchSetItemSets.ItemSet.Custodian").Where(x => x.BatchId == batchId).SingleOrDefault();
You are close with the attributes, but they need to be changed:
[HasSelfValidation]
public class Batch
{
public int BatchId { get; set; }
public string BatchName { get; set; }
[Include]
[Composition]
[Association("FK_Batch_BathSetItemSet", "BatchId", "BatchId", IsForeignKey = false)]
public virtual ICollection<BatchSetItemSet> BatchSetItemSets { get; set; }
}
public class BatchSetItemSet
{
public int BatchSetIdItemSetId { get; set; }
public int BatchId { get; set; }
public Nullable<int> ItemSetId { get; set; }
public string CreatedBy { get; set; }
[Include]
[Association("FK_Batch_BathSetItemSet", "BatchId", "BatchId")]
public Batch Batch { get; set; }
[Include]
[Association("FK_BathSetItemSet_ItemSet", "ItemSetId", "ItemSetId")]
public ItemSet ItemSet { get; set; }
}
public class ItemSet
{
public int ItemSetId { get; set; }
public int CustodianId { get; set; }
public string ItemSetName { get; set; }
[Include]
[Composition]
[Association("FK_BathSetItemSet_ItemSet", "ItemSetId", "ItemSetId", IsForeignKey = false)]
public virtual ICollection<BatchSetItemSet> BatchSetItemSets { get; set; }
[Include]
[Association("FK_ItemSet_Custodian", "CustodianId", "CustodianId")]
public virtual Custodian Custodian { get; set; }
}
The AssociationAttribute .ctor is defined as:
AssociationAttribute(string name, string thisKey, string otherKey)
It should be configured as:
name: A unique name shared by each end of the relationship
thisKey: The name of the Property on this object that represents the key or foreign key
otherKey: The name of the Property on the other object that represents the key or foreign key
IsForeignKey: A property on AssociationAttribute to indicate if this end of the relationship is the primary key or the foreign key. It defaults to true (meaning this navigation property is a Foreign Key). By setting it to false, you indicate to WCF RIA that this object contains the Primary Key. For all AssociationAttribute usages with a given name, only one is allowed to have IsForeignKey = false. Otherwise, you will get a build error.