I have following three classes
Om_MembershipCharges Class
public class Om_MembershipCharges
{
[Key]
public Int32 MembershipChargesID { get; set; }
public Decimal Amount { get; set; }
public Int16 PerMonth { get; set; }
public Int16? CountryID { get; set; }
public Int16 MemebershipTypeID { get; set; }
public virtual Om_MembershipType MemebershipType { get; set; }
public virtual Om_Country Country { get; set; }
}
Om_MembershipType Class
public class Om_MembershipType
{
[Key]
public Int16 MemebershipTypeID { get; set; }
public String MemebershipType { get; set; }
public Boolean IsDefaultMembership { get; set; }
public virtual ICollection<Om_MembershipCharges> MembershipCharges { get; set; }
}
Om_Country Class
public class Om_Country
{
[Key]
public Int16 CountryID { get; set; }
public String CountryName { get; set; }
public Boolean IsActive { get; set; }
public Int16? CurrencyID { get; set; }
public Int32? MembershipChargesID { get; set; }
public virtual Om_Currency Currency { get; set; }
public Om_MembershipCharges MembershipCharges { get; set; }
}
Below is my method that fetches all the Membership Charges using MembershipCharges Property in Om_MembershipType Class. I am using Include to get the collection.
public async Task<KeyValuePair<String, Om_MembershipType>> ListByMType(String mType)
{
try
{
using (var membershipChargesContext = new DatabaseTables())
{
using (var transaction = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted },
TransactionScopeAsyncFlowOption.Enabled))
{
membershipChargesContext.Configuration.ProxyCreationEnabled = false;
var data = await membershipChargesContext
.tblMembershipType
.Where(i => i.MemebershipType == membershipType)
.Include(i => i.MembershipCharges)
.FirstOrDefaultAsync();
transaction.Complete();
return new KeyValuePair<String, Om_MembershipType>("", data);
}
}
}
catch (Exception ex)
{
var exception = ex.Message;
if (ex.InnerException != null)
exception = ex.InnerException.ToString();
return new KeyValuePair<String, Om_MembershipType>(exception, null);
}
}
Is there any way to get the Country Instance in the Membership Charges collection ?
Is there any way to get the Country Instance in the Membership Charges collection?
Yes:
var data = await membershipChargesContext
.tblMembershipType
.Where(i => i.MemebershipType == membershipType)
.Include(i => i.MembershipCharges.Select(m => m.Country))
.FirstOrDefaultAsync();
You can expand an expression in the Include statement by subsequent Select statements to include nested navigation properties.
Related
A user can add an event they want to their favorites. Below are the entities I have opened for this and the links between them.
Event:
public class Event : EntitySoftDeletableIntKey
{
public string Title { get; set; }
public string ShortContent { get; set; }
public string Place { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int EventDetailId { get; set; }
public EventDetail EventDetail { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
public List<Tag>? Tags { get; set; } = new List<Tag>();
public List<Comment>? Comments { get; set; } = new List<Comment>();
public ApplicationUser? ApplicationUser { get; set; }
public int? ApplicationUserId { get; set; }
public List<AttendedEvent>? AttendedEvents { get; set; } = new List<AttendedEvent>();
public List<FavoriteEvent>? FavoriteEvents { get; set; }
}
User:
public class ApplicationUser : IdentityUser<int>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public List<FavoriteEvent>? FavoriteEvents { get; set; } = new List<FavoriteEvent>();
public List<Event>? Events { get; set; } = new List<Event>();
public List<AttendedEvent>? AttendedEvents { get; set; } = new List<AttendedEvent>();
}
FavoriteEvent :
public class FavoriteEvent : EntitySoftDeletableIntKey
{
public int? EventId;
public Event? Event;
public int? ApplicationUserId { get; set; }
public ApplicationUser? ApplicationUser { get; set; }
}
Link Bbetween :
modelBuilder.Entity<FavoriteEvent>()
.HasKey(fe => new { fe.EventId, fe.ApplicationUserId });
modelBuilder.Entity<FavoriteEvent>()
.HasOne(fe => fe.Event)
.WithMany(e => e.FavoriteEvents)
.HasForeignKey(ae => ae.EventId).OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<FavoriteEvent>()
.HasOne(fe => fe.ApplicationUser)
.WithMany(u => u.FavoriteEvents)
.HasForeignKey(fe => fe.ApplicationUserId).OnDelete(DeleteBehavior.Restrict);
When the user adds an event to the favoriteevent list, I get the error in the header. I couldn't solve it anyway. Thank you in advance for your help.
public async Task<Unit> Handle(AddEventToFavCommandRequest request, CancellationToken cancellationToken)
{
var #event = await _unitOfWork.GetReadRepository<Event>().GetSingle(e => e.Id == request.EventId);
var currentUser = await _userManager.Users.FirstOrDefaultAsync(u => u.Id == request.ApplicationUserId);
currentUser.FavoriteEvents.Add(new FavoriteEvent()
{
EventId = #event.Id,
ApplicationUserId = currentUser.Id
});
return Unit.Value;
}
public async Task<int> Save(CancellationToken cancellationToken = new CancellationToken())
{
var datas = _context.ChangeTracker.Entries<EntitySoftDeletableIntKey>();
foreach (var data in datas)
{
_ = data.State switch
{
EntityState.Added => data.Entity.CreatedDate = DateTime.UtcNow,
EntityState.Modified => data.Entity.ModifiedDate = DateTime.UtcNow,
};
}
return await _context.SaveChangesAsync(cancellationToken);
}
automapper always convert null objects and it not throwing any exception here is my models and the methos i used...what i want when i initialize ProductDetailsModel inside ProductModel model i want to be initialized also inside Product model... both objects ProductDetailsModel and CategoryModel inside ProductModel they not initialized in Product
public class Product
{
[Key]
public int ID { get; set; }
public int? IDCategory { get; set; }
public string Name { get; set; }
public string Price { get; set; }
public int Quantity { get; set; }
public List<Image> Images { get; set; }
[ForeignKey("IDCategory")]
public Category Category { get; set; }
public virtual ProductDetails ProductDetails { get; set; }
}
public class ProductModel
{
[Key]
public int ID { get; set; }
[Required(ErrorMessage ="حقل الزامي")]
public int? IDCategory { get; set; }
public string Name { get; set; }
[Required(ErrorMessage = "حقل الزامي")]
[RegularExpression("([1-9][0-9]*)", ErrorMessage = "يجب ادخال ارقام فقط")]
public string Price { get; set; }
[Required(ErrorMessage = "حقل الزامي")]
[RegularExpression("([1-9][0-9]*)", ErrorMessage = "يجب ادخال ارقام فقط")]
public string Quantity { get; set; }
public List<ImageModel> Images { get; set; } = new List<ImageModel>();
public CategoryModel CategoryModel { get; set; } = new CategoryModel();
public ProductDetailsModel ProductModelDetails { get; set; } = new ProductDetailsModel();
}
public class ProfileMapper : Profile
{
public ProfileMapper()
{
CreateMap<ProductModel, Product>().ReverseMap();
CreateMap<ImageModel, Image>().ReverseMap();
CreateMap<CategoryModel, Category>().ReverseMap();
CreateMap<ProductDetailsModel, ProductDetails>().ReverseMap();
}
}
public async Task Add(ProductModel entity)
{
try
{
var theObject = mapper.Map<ProductModel, Product>(entity);
await Db.Product.AddAsync(theObject);
}
catch (Exception e)
{
await jSRuntime.ToastrError(e.Message);
}
}
private async Task AddProductsForm()
{
await UnitOfWork.ProductRepository.Add(new ProductModel {ProductModelDetails = new ProductDetailsModel { Details="gg"},Images = new List<ImageModel> { new ImageModel { ImageUrl = defaultImage } } });
await UnitOfWork.Complete();
ProductModels = (ICollection<ProductModel>)await UnitOfWork.ProductRepository.GetALL();
}
Your mapping does not include the name changes.
For example from Category => CategoryModel
CreateMap<Product, ProductModel>()
.ForMember(dest => dest.CategoryModel, opt => opt.MapFrom(src => src.Category))
.ReverseMap();
When attempting a straight forward projection using Entity Framework Core and Linq, I am getting an "Argument types do not match" exception.
I have looked into possible causes and have narrowed it down to the Select that is causing the error (see below). There is a GitHub issue describing a similar situation with simple types and optional navigation entities, but none of the suggested solutions have worked for me. It is not a nullable type and I have tried casting or using Value on any child properties. I have also tried setting the relationship to required in the DbContext which isn't exactly ideal.
Here is the Linq query in the repository:
return await _dashboardContext.PresetDashboardConfig
.Where(config => config.DashboardTypeId == dashboardType && config.OrganisationType = organisationType)
.GroupBy(config => config.GroupId)
.Select(config => new DashboardConfigDTO
{
DashboardType = config.First().DashboardTypeId,
OrganisationId = organisationId,
WidgetGroups = config.Select(group => new WidgetGroupDTO
{
Id = group.Id,
Name = group.GroupName,
TabOrder = group.TabOrder,
// Problem Select below:
Widgets = group.Widgets.Select(widget => new WidgetConfigDTO
{
IndicatorId = widget.IndicatorId,
ScopeId = widget.ScopeId.ToString(),
ParentScopeId = widget.ParentScopeId.ToString(),
WidgetType = widget.WidgetType,
WidgetSize = widget.WidgetSize,
Order = widget.Order
})
})
})
.SingleOrDefaultAsync();
And the entities:
public class DashboardConfig
{
public int Id { get; set; }
public int DashboardTypeId { get; set; }
public int OrganisationType {get; set; }
public int GroupId { get; set; }
public string GroupName { get; set; }
public int TabOrder { get; set; }
}
public class PresetDashboardConfig : DashboardConfig
{
public ICollection<PresetWidgetConfig> Widgets { get; set; }
}
public class WidgetConfig
{
public int Id { get; set; }
public int IndicatorId { get; set; }
public long ScopeId { get; set; }
public long? ParentScopeId { get; set; }
public int WidgetType { get; set; }
public int WidgetSize { get; set; }
public int Order { get; set; }
}
public class PresetWidgetConfig : WidgetConfig
{
public int PresetDashboardConfigId { get; set; }
}
And finally, the DbContext ModelBuilder:
modelBuilder.Entity<PresetDashboardConfig>(entity =>
{
entity.Property(e => e.GroupName)
.HasMaxLength(32)
.IsUnicode(false);
entity.HasMany(e => e.Widgets)
.WithOne();
});
Below are the DTO classes as per Henk's comment:
public class DashboardConfigDTO
{
public int DashboardType { get; set; }
public int OrganisationId { get; set; }
public IEnumerable<WidgetGroupDTO> WidgetGroups { get; set; }
}
public class WidgetGroupDTO
{
public int Id { get; set; }
public string Name { get; set; }
public int TabOrder { get; set; }
public IEnumerable<WidgetConfigDTO> Widgets { get; set; }
}
public class WidgetConfigDTO
{
public int IndicatorId { get; set; }
public string ScopeId { get; set; }
public string ParentScopeId { get; set; }
public int WidgetType { get; set; }
public int WidgetSize { get; set; }
public int Order { get; set; }
}
I have a method where (artist and genre) throws null reference exception, when i use select clause. if i don't use select clause then it can't convert system.collections.generic.list to system.collections.generic.ienumerable.
public ActionResult Attending()
{
var userId = User.FindFirst(ClaimTypes.NameIdentifier).Value;
var gigs = _context.Attendances.Include(a => a.Gig.Artist).Include(a => a.Gig.Genre).Where(a => a.AttendeeId == userId).ToList();
var viewModel = new GigsViewModel()
{
UpcomingGigs = gigs,
ShowActions = User.Identity.IsAuthenticated,
Heading = "Gigs I'm Attending"
};
return View("Gigs", viewModel);
}
Here is my ViewModel:
public class GigsViewModel
{
public IEnumerable<Gig> UpcomingGigs { get; set; }
public bool ShowActions { get; set; }
public string Heading { get; set; }
}
Here is my Attendance class
public class Attendance
{
public Gig Gig { get; set; }
public ApplicationUser Attendee { get; set; }
[Key]
public int GigId { get; set; }
[Key]
public string AttendeeId { get; set; }
}
An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception.
I'm using EF Code first and I'm getting error above when I trying do this:
public ActionResult CreateTransaction(TransactionViewModel model)
{
try
{
if (model.MemberId != 0 && model.SubcategoryId != 0 & model.CategoryId != 0)
{
Transaction t = new Transaction();
t.Amount = model.Amount;
t.Comment = model.Comment;
t.Date = DateTime.Now;
t.TransactionSubcategory = db.Subcategories.Find(model.SubcategoryId);//and i have error in this line
//i tried also this code below but it's the same error
//db.Subcategories.Find(model.SubcategoryId).Transactions.Add(t);
db.Members.Find(model.MemberId).Transactions.Add(t);
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
return RedirectToAction("CreateTransaction") ;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
return RedirectToAction("CreateTransaction");
}
}
And there is my model
public class Subcategory
{
public Subcategory()
{
IsGlobal = false;
Transactions = new List<Transaction>();
}
public int Id { get; set; }
public string Name { get; set; }
public TransactionType TypeOfTransaction { get; set; }
public Category OwnerCategory { get; set; }
public List<Transaction> Transactions { get; set; }
public bool IsGlobal { get; set; }
}
public class Transaction
{
public int Id { get; set; }
public Decimal Amount { get; set; }
public DateTime Date { get; set; }
public string Comment { get; set; }
public Subcategory TransactionSubcategory { get; set; }
public Member OwnerMember { get; set; }
}
I don't know why thats happen because in database in Transaction table i see there is column with FK.
If you need there is rest of the model
public class Budget
{
public Budget()
{
Members = new List<Member>();
}
public int Id { get; set; }
public string BudgetName { get; set; }
public string OwnerName { get; set; }
public DateTime CreatedTime { get; set; }
public List<Member> Members { get; set; }
}
public class Category
{
public Category()
{
IsGlobal = false;
}
public int Id { get; set; }
public string Name { get; set; }
public List<Subcategory> Subcategories { get; set; }
public Budget OwnerBudget { get; set; }
public bool IsGlobal { get; set; }
}
public class Member
{
public Member()
{
Transactions = new List<Transaction>();
}
public Budget OwnerBudget { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreatedTime { get; set; }
public List<Transaction> Transactions { get; set; }
}
public enum TransactionType
{
Income,
Expenditure
}
Try adding
public int TransactionSubcategoryId { get; set; }
public int OwnerMemberId { get; set; }
In your Transaction class.