I am trying to join two tables using Entity Framework but getting System.InvalidOperationException error. The error message is:
The property 'MasterCompany' is not a navigation property of entity type 'UnitOfMeasure'. The 'Include(string)' method can only be used with a '.' separated list of navigation property names.`.
I am not sure why it is throwing it.
Other Attempts:
I also tried adding public virtual MasterCompany MasterCompany { get; set; } in UnitOfMeasure but that throws Invalid column error.
Also added [Key] in MasterCompany table for MasterCompanyId.
But both of these changes throws Invalid column name 'IsDeleted'. error.
DAL Models:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
{
public DbSet<UnitOfMeasure> UnitOfMeasure { get; set; }
public DbSet<MasterCompany> MasterCompany { get; set; }
}
public class UnitOfMeasure : PasBase, IAudit
{
[Key]
public long UnitOfMeasureId { get; set; }
public string Description { get; set; }
public string ShortName { get; set; }
public string Memo { get; set; }
public string Standard { get; set; }
// [ForeignKey("MasterCompanyId")]
public Int32 MasterCompanyId { get; set; }
public bool IsActive { get; set; }
public bool IsDeleted { get; set; }
[NotMapped]
public string UploadStatus { get; set; }
[ForeignKey("MasterCompanyId")]
public virtual MasterCompany MasterCompany { get; set; }
}
public class MasterCompany:AuditableEntity
{
public int MasterCompanyId { get; set; }
public string CompanyName { get; set; }
public string TaxId { get; set; }
public string EmailAddress { get; set; }
public string Address { get; set; }
public bool? IsActive { get; set; }
}
Repository:
private ApplicationDbContext _appContext => (ApplicationDbContext)_context;
public IEnumerable<DAL.Models.UnitOfMeasure> getUnitOfMeasureData()
{
return _appContext.UnitOfMeasure
.Include("MasterCompany")
.Where(c => c.IsDeleted == false || c.IsDeleted == null)
.OrderByDescending(c => c.UnitOfMeasureId)
.ToList();
}
You need to add a MasterCompany property in the class UnitOfMeasure
public class UnitOfMeasure : PasBase, IAudit
{
[Key]
public long UnitOfMeasureId { get; set; }
public string Description { get; set; }
public string ShortName { get; set; }
public string Memo { get; set; }
public string Standard { get; set; }
public Int32 MasterCompanyId { get; set; }
[ForeignKey("MasterCompanyId")]
public MasterCompany MasterCompany { get; set; }
public bool IsActive { get; set; }
public bool IsDeleted { get; set; }
[NotMapped]
public string UploadStatus { get; set; }
}
Related
My Club has many members so I have added the following virtual property Members my question is when I want to list the club members shouldn't adding just the virtual load this into lazy loading am using .net 5.0.1 at present.
var members = _context.Clubs.Include(c=>c.Members).Where(w => w.ClubId == tennantId ).ToList();
When I look at var members even when the members have been included it is zero even though the teannatId matches.
public class MSFSAddonDBContext : IdentityDbContext<ApplicationUser>
{
public MSFSAddonDBContext(DbContextOptions<MSFSAddonDBContext> options)
: base(options)
{
}
public DbSet<Club> Clubs { get; set; }
public virtual List<ApplicationUser>? Members { get; set; }
}
This is my controller method.
public void IActionResult ClubMembers()
{
var tennantId = GetTennantId().Result;
var members = _context.Clubs.Include(c=>c.Members).Where(w => w.ClubId == tennantId ).ToList();
return View(members);
}
There are two members references at top level and inside the clubs.
This is the club class
public class Club
{
public int Id { get; set; }
public Guid? TeannatId { get; set; }
public Guid? ClubId { get; set; }
public Guid? UserId { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public string? Url { get; set; }
public int? ClubLikes { get; set; }
public int? ClubDislikes { get; set; }
public int? MembersCount { get; set; }
public string? Logo { get; set; }
public List<Flight>? Flights { get; set; }
public string? ThumbNail { get; set; }
public DateTimeOffset? GpdrRemoveRequestDate { get; set; }
public bool? isGpdrRemoveRequest { get; set; }
public DateTimeOffset? BannedTime { get; set; }
public TimeSpan? BanPeriod { get; set; }
public bool? isBanned { get; set; }
public bool? isActive { get; set; }
public bool? isDeleted { get; set; }
public DateTime? CreatedDate { get; set; }
public string? CreatedBy { get; set; }
public virtual List<ApplicationUser>? Members { get; set; }
}
Edit 2
This is the application user class.
public class ApplicationUser : IdentityUser
{
public enum UserTypeEnum
{
Guest=0,
User=1,
Author=2,
AddonOwner=3,
GroupOwner=5,
ClubMember=6,
ClubAdmin=7,
SuperAdmin=199,
BandUser=999
}
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? GamerTag { get; set; }
public bool? isOnline { get; set; }
public int? UserType { get; set; }
public Guid? TennantId { get; set; }
public Guid? ClubId { get; set; }
public List<Badges>? Badges { get; set; }
}
NB As always with ef the primary keys in all my tables are the Id column thanks
I am using code first approach with Entity Framework 6. Three of my model classes implements inheritance and each of these model has collection which also implement inheritance. I am using TPH inheritance strategy. Everything works fine and I can insert/update with no problem at all. However, I get when I try to read data from the repo. The I get is shown below.
I have include my models, entity configuration and the line that throws this exception:
The include path expression must refer to a navigation property defined on the type. Use dotted paths for reference navigation properties and the select operator for collection navigation properties
Code:
public abstract class OrderSup
{
public OrderSup()
{
DetailOrderSups = new HashSet<DetailOrderSup>();
}
public int Id { get; set; }
public string Description { get; set; }
public decimal AmountPaid { get; set; }
public DateTime DateEntered { get; set; }
public string CusSupCode { get; set; }
public decimal NetAmount { get; set; }
public decimal TaxAmount { get; set; }
public string DespatchSatus { get; set; }
public string Reference { get; set; }
}
public abstract class DetailOrderSup
{
[Key, Column(Order = 0)]
public virtual int OrderId { get; set; }
[Key, Column(Order = 1)]
public virtual int ProductId { get; set; }
public virtual Product OrderedProducts { get; set; }
public InvoiceType InvoiceType { get; set; }
public virtual OrderSup OrderSup { get; set; }
}
public class Order : OrderSup
{
public int SalesOrderNumber { get; set; }
public InvoiceType InvoiceType { get; set; }
}
public class PurchaseOrder : OrderSup
{
public string OrderStatus { get; set; }
//public string AlocationStatus { get; set; }
public int InvoiceNumber { get; set; }
}
public class PurchaseOrderDetails : DetailOrderSup
{
public bool IsOrderPaid { get; set; }
public decimal Outstanding { get; set; }
public decimal AmountPaid { get; set; }
public bool IsDisputed { get; set; }
}
public class OrderDetails: DetailOrderSup
{
public bool IsOrderPaid { get; set; }
public decimal Outstanding { get; set; }
}
public IEnumerable<PurchaseOrder> GetPurchaseOrders()
{
// THIS IS LINE THAT THROWS EXCEPTION
return this.AppContext.Orders.OfType<PurchaseOrder>()
.Include(o => o.DetailOrderSups.OfType<PurchaseOrderDetails>());
}
class OrderSupConfiguration : EntityTypeConfiguration<OrderSup>
{
public OrderSupConfiguration()
{
HasMany(p => p.DetailOrderSups)
.WithRequired(o => o.OrderSup)
.HasForeignKey(o => o.OrderId);
}
}
Please what am I doing wrong?
Thanks in advance for your assistance
I am trying to map a model to a view, but I receive the error above when I am trying to display all my elements, since Automapper doesn't recognize the IEnumerable I think. I receive the error when I am trying to map FixedAssets to FixedAssetsView and FixedAssetsView to FixedAssets.
Here are the objects I am trying to map:
FixedAssets
public class FixedAssets : IEntityBase
{
public int ID { get; set; }
public string name { get; set; }
public virtual ICollection<Category> category { get; set; }
public string serialNo { get; set; }
public string provider { get; set;
public DateTime acquisitionDate { get; set; }
public DateTime warrantyEnd { get; set; }
public int inventoryNo { get; set; }
public string allocationStatus { get; set; }
public string owner { get; set; }
public DateTime allocationDate { get; set; }
public string serviceStatus { get; set; }
public string serviceResolution { get; set; }
public FixedAssets()
{
this.category = new HashSet<Category>();
}
}
FixedAssetsView
public class FixedAssetsView
{
public int ID { get; set; }
public string name { get; set; }
public virtual ICollection<CategoryView> category { get; set; }
public string serialNo { get; set; }
public string provider { get; set; }
public DateTime acquisitionDate { get; set; }
public DateTime warrantyEnd { get; set; }
public int inventoryNo { get; set; }
public string allocationStatus { get; set; }
public string owner { get; set; }
public DateTime allocationDate { get; set; }
public string serviceStatus { get; set; }
public string serviceResolution { get; set; }
}
Category
public class Category : IEntityBase
{
public int ID { get; set; }
public string categoryName { get; set; }
public virtual ICollection<FixedAssets> fixedasset { get; set; }
public Category()
{
this.fixedasset = new HashSet<FixedAssets>();
}
}
CategoryView
public class CategoryView
{
public int ID { get; set; }
public string categoryName { get; set; }
public virtual ICollection<FixedAssetsView> fixedasset { get; set; }
}
Automapper configuration
Mapper.Initialize(x =>
{
x.CreateMap<FixedAssets, FixedAssetsView>();
x.CreateMap<FixedAssetsView, FixedAssets>();
x.CreateMap<Category, CategoryView>();
x.CreateMap<CategoryView, Category>();
});
I believe you need a .ForMember in your Mapper initialization.
eg:
Mapper.CreateMap<IEnumerable<Source>, IEnumerable<Target>>()
.ForMember(f => f, mp => mp.MapFrom(
mfrom => mfrom.Select(s => AutoMapper.Mapper.Map(s, new Target())
)
);
In my project I need to map objects from the external systems to DTOs. The object I want to map is:
public class PriceLists : List<PriceList> { }
I get the idea of mapping properties within the class but having difficulty finding a solution for this case. My DTO will preferably be "identical" to this source class to make it as simple as possible for the moment:
public class PriceListsDTO : List<PriceListDTO> { }
Is there a simple solution or do I need to refactor my DTO object?
Thanks.
Edit: I have tried creating mapping for a list of Price lists without success regarding this problem.
Mapper.Initialize(cfg => { cfg.CreateMap<PriceList>, <PriceListDTO>(); });
Mapper.Initialize(cfg => { cfg.CreateMap<IList<PriceList>, IList<PriceListDTO>>(); });
Edit2:
public class PriceList
{
public string Agreement { get; set; }
public Currency Currency { get; set; }
public string Description { get; set; }
public Nullable<DateTime> EndDate { get; set; }
public int Id { get; set; }
public Nullable<Guid> ImageKey { get; set; }
public bool IsBid { get; set; }
public bool IsLimitedToStock { get; set; }
public bool IsPrimary { get; set; }
public bool IsPublic { get; set; }
public string Name { get; set; }
public Nullable<DateTime> StartDate { get; set; }
public int Type { get; set; }
}
public class PriceListDTO
{
public string Agreement { get; set; }
public CurrencyViewModel Currency { get; set; }
public string Description { get; set; }
public DateTime? EndDate { get; set; }
public int Id { get; set; }
public Guid? ImageKey { get; set; }
public bool IsBid { get; set; }
public bool IsLimitedToStock { get; set; }
public bool IsPrimary { get; set; }
public bool IsPublic { get; set; }
public string Name { get; set; }
public DateTime? StartDate { get; set; }
public int Type { get; set; }
}
And the Currency class and DTO only contains string properties.
From the code you've given, you never actually told AutoMapper to associate the DTO with the model class. If you call Initialize twice, the second will REMOVE any previous mappings. Try updating your configuration to do the following:
Mapper.Initialize( cfg => {
cfg.CreateMap<PriceList, PriceListDTO>()
.ReverseMap();
// Not sure if this is required if you already have the model/dto map
cfg.CreateMap<IList<PriceList>, IList<PriceListDTO>>();
cfg.AssertConfigurationIsValid();
});
public class PriceList
{
public string Agreement { get; set; }
public Currency Currency { get; set; }
public string Description { get; set; }
public Nullable<DateTime> EndDate { get; set; }
public int Id { get; set; }
public Nullable<Guid> ImageKey { get; set; }
public bool IsBid { get; set; }
public bool IsLimitedToStock { get; set; }
public bool IsPrimary { get; set; }
public bool IsPublic { get; set; }
public string Name { get; set; }
public Nullable<DateTime> StartDate { get; set; }
public int Type { get; set; }
}
public class PriceListDTO
{
public string Agreement { get; set; }
public Currency Currency { get; set; }
public string Description { get; set; }
public DateTime? EndDate { get; set; }
public int Id { get; set; }
public Guid? ImageKey { get; set; }
public bool IsBid { get; set; }
public bool IsLimitedToStock { get; set; }
public bool IsPrimary { get; set; }
public bool IsPublic { get; set; }
public string Name { get; set; }
public DateTime? StartDate { get; set; }
public int Type { get; set; }
}
after that try automapper.mapper.createmap it
will work for you otherwise you need to use formember method to map
properties of currency with currencyviewmodel one by one because
object are different to each other just try with it. hope it will help
for you . Thanks
I am trying to figure out why EF is lazy loading everything but my ApplicationUser property. I am using a generic repository pattern with the following domain object.
public class Order
{
[Key]
public Guid Id { get; set; }
public int PaymentTransactionId { get; set; }
public string CustomerId { get; set; }
public int ChildId { get; set; }
public DateTime PickUpDate { get; set; }
public PickUpTime PickUpTime { get; set; }
public string Notes { get; set; }
public decimal Discount { get; set; }
public decimal SubTotal { get; set; }
public decimal Tax { get; set; }
public decimal Total { get; set; }
public DateTime DateCreated { get; set; }
public string CreatedBy { get; set; }
public OrderStatus Status { get; set; }
public virtual ApplicationUser Customer { get; set; }
public virtual Child Child { get; set; }
public virtual PaymentTransaction PaymentTransaction { get; set; }
public virtual PromotionCode PromotionCode { get; set; }
}
I've tried doing the following
context.Configuration.LazyLoadingEnabled = true;
All the virtual properties except ApplicationUser get populated when I retrieve the entity from the database.
DBCONTEXT
public class DatabaseContext : IdentityDbContext<ApplicationUser>
{
public DatabaseContext()
: base("name=DefaultContext")
{
Database.SetInitializer<DatabaseContext>(null);
Configuration.LazyLoadingEnabled = true;
}
public IDbSet<PromotionCode> Promotions { get; set; }
public IDbSet<PaymentTransaction> PaymentTransactions { get; set; }
public IDbSet<BakeryOrder> BakeryOrders { get; set; }
public IDbSet<Child> Children { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<BakeryOrder>().Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>()
.ToTable("Users");
modelBuilder.Entity<ApplicationUser>()
.ToTable("Users");
}
public static DatabaseContext Create()
{
return new DatabaseContext();
}
}
REPOSITORY
public class Repository<T> : IRepository<T> where T : class
{
protected DatabaseContext Context;
public Repository(DatabaseContext context)
{
Context = context;
}
public IEnumerable<T> Get()
{
return Context.Set<T>();
}
}
SERVICE
public IEnumerable<Order> Get()
{
return _orderRepository.Get();
}
Am I missing something here? This did work for some time and suddenly stopped, I have no idea why... the code base hasn't changed according to the commit logs.
Entity framework doesn't know what key to map it to because you don't have any property named "ApplicationUserId" so you must explicitly add the attribute pointing to the right foreign key.
public class Order
{
[Key]
public Guid Id { get; set; }
public int PaymentTransactionId { get; set; }
public string CustomerId { get; set; }
public int ChildId { get; set; }
public DateTime PickUpDate { get; set; }
public PickUpTime PickUpTime { get; set; }
public string Notes { get; set; }
public decimal Discount { get; set; }
public decimal SubTotal { get; set; }
public decimal Tax { get; set; }
public decimal Total { get; set; }
public DateTime DateCreated { get; set; }
public string CreatedBy { get; set; }
public OrderStatus Status { get; set; }
[ForeignKey("CustomerId")]
public virtual ApplicationUser Customer { get; set; }
public virtual Child Child { get; set; }
public virtual PaymentTransaction PaymentTransaction { get; set; }
public virtual PromotionCode PromotionCode { get; set; }
}