EF core order by navigation property - sql-server

I have an entity relationship like this.
public class Provider
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<ProviderPod> ProviderPods { get; set; } = new List<ProviderPod>();
}
public class ProviderPod
{
public int Id { get; set; }
public int ProviderId { get; set; }
public int PodId { get; set; }
public virtual Provider Provider { get; set; }
public virtual Pod Pod { get; set; }
}
public class Pod
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ProviderPod> ProviderPods { get; set; } = new List<ProviderPod>();
}
I need to order the 'Provider' entity by it's navigation property ProviderPods' "Name" separated by a comma. Something like this
IQueryable<Provider> entityQuery = context.Providers.AsQueryable();
//Need to enter Appropriate query below
entityQuery = entityQuery.OrderByDescending(x => string.Join(", ", x.ProviderPods.Select(y => y.Pod.Name)));
var list = entityQuery.Take(12).ToList();
What would be the best way to achieve this ordering?

Related

Entities with problems and limitations

I have these entities:
public class Project : Base
{
public string Name { get; set; }
public string Description { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public ProjectStatus CurrentStatus { get; set; } = ProjectStatus.New;
public List<StatusHistory>? StatusHistories { get; set; }
public Team? Team { get; set; }
public int? TeamId { get; set; }
// public ProgressTrackerValue trackerValue { get; set; }
public List<AttachedFile> AttachedFiles { get; set; }
}
public class Task : Base
{
public string Name { get; set; }
public string Description { get; set; }
public DateTime? EstimatedDueDate { get; set; }
public DateTime? ActualDueDate { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; } // ?? End DATE same as ActualDueDate
public TaskStatus CurrentStatus { get; set; } = TaskStatus.Draft;
public int ProjectId { get; set; }
public Project Project { get; set; }
public List<StatusHistory> StatusHistories { get; set; }
public TaskType TaskType { get; set; }
public TaskPriority Priority { get; set; }
public float ? DurationProgress { get; set; }
public List<AttachedFile> AttachedFiles { get; set; }
}
public class Team : Base
{
public string TeamLeaderId { get; set; }
public List<TeamMember>? TeamMembers { get; set; }
public virtual Project Project { get; set; }
}
public class AttachedFile : Base
{
public string OriginalFileName { get; set; }
public string FileName { get; set; }
public string MimeType { get; set; }
public string FileType { get; set; }
public string OwnerType { get; set; }
public int OwnerId {get; set;}
public string FilePath { get; set; }
public long FileSize { get; set; }
}
public class Comment : Base
{
public string Content { get; set; }
public int? ParentCommentId { get; set; }
public List<Comment>? Replies { get; private set; }
public Task Task { get; set; }
public int taskId { get; set; }
public List<AttachedFile>? AttachedFiles { get; set; }
}
public class StatusHistory : Base
{
public string OwnerType { get; set; }
public int OwnerId {get; set;}
public string State { get; set; }
}
public class TaskEmployee : Base
{
public int TaskId { get; set; }
public Task Task { get; set; }
public string EmployeeId { get; set; }
}
public class TeamMember : Base
{
public string UserId { get; set; }
}
What can I do to improve the above entities? Any suggestions.
Also there is UserId,EmployeeId,TeamLeaderId.... all of these supposed to be FK to IdentityUser but this project is isolated from Identity and i can't find a way to link them together. if there is a suggestion on how could I make such relationship in EFCore. (I could make relationship manually but I can't put navigation properties for Identity inside these entities thus not benefiting from EFCore).
Finally there is OwnerType, OwnerId, for example in the AttachedFile entity the attached file could be related to Project, Task, Comment. So I will store the type and id for them in these fields, the problem however that I will not benefit form EF Core functionality this way. For example: I must write SQL manually for every query.
currently the schema look like this:
enter image description here

Migration conflicts in net core Entity Framework

I have two tables in my SQL Server database - one for categories:
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
[ForeignKey("ParentId")]
public Category Parent { get; set; }
}
And then the Assistant table:
public class Assistant
{
public int Id { get; set; }
public int UserId { get; set; }
public DateTime CreatedAtUtc { get; set; }
public Status Status { get; set; }
public int? CategoryId { get; set; }
[ForeignKey("CategoryId")]
public Category Category { get; set; }
}
When I try to make a migration I get this error:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_Assistants_Categories_CategoryId". The conflict occurred in database "Pirma
isMsSql", table "dbo.Categories", column 'Id'.
I have no idea why.
Thanks
Fix your classes:
public partial class Assistent
{
[Key]
public int Id { get; set; }
public int UserId { get; set; }
public User User{ get; set; }
public DateTime CreatedAtUtc { get; set; }
public int StatusId { get; set; }
public Status Status { get; set; }
public int? CategoryId { get; set; }
[ForeignKey(nameof(CategoryId))]
[InverseProperty("Assistents")]
public virtual Category Category { get; set; }
}
public partial class Category
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
[ForeignKey(nameof(ParentId))]
[InverseProperty(nameof(Category.InverseParent))]
public virtual Category Parent { get; set; }
[InverseProperty(nameof(Assistent.Category))]
public virtual ICollection<Assistent> Assistents { get; set; }
[InverseProperty(nameof(Category.Parent))]
public virtual ICollection<Category> InverseParent { get; set; }
}
This is db context:
public partial class AssistentsContext : DbContext
{
public AssistentsContext()
{
}
public AssistentsContext(DbContextOptions<AssistentsContext> options)
: base(options)
{
}
public virtual DbSet<Assistent> Assistents { get; set; }
public virtual DbSet<Category> Categories { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Assistent>(entity =>
{
entity.HasOne(d => d.Category)
.WithMany(p => p.Assistents)
.HasForeignKey(d => d.CategoryId);
});
modelBuilder.Entity<Category>(entity =>
{
entity.HasOne(d => d.Parent)
.WithMany(p => p.InverseParent)
.HasForeignKey(d => d.ParentId);
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}

Angularjs WebApi is not working in Asp.net MVC Entity Framework

This error is Occur after running the web application. this is picture of inspect elements of google chrome.
See Image
See Second Image
i want to us entity framework
here is class code... when i comment the
public virtual List tblproduct { get; set; } and
public virtual List tblproduct { get; set; } this its working perfetcly how to completety use entity framework mvc in it
[Table("tblCatagory")]
public class AddCatagory
{
public int Id { get; set; }
[StringLength(56)]
public string CataName { get; set; }
public virtual List<Product> tblproduct { get; set; }
//public virtual List<AddSubCatagory> tblsubcatagory { get; set; }
}
[Table("tblSubCatagory")]
public class AddSubCatagory
{
public int Id { get; set; }
[StringLength(56)]
public string SubCataName { get; set; }
public int AddCatagoryId { get; set; }
public virtual AddCatagory tblcatagory { get; set; }
public virtual List<Product> tblproduct { get; set; }
}
product class code
[Table("tblProduct")]
public class Product
{
public int Id { get; set; }
[StringLength(56)]
public string ProductName { get; set; }
[StringLength(156)]
public string ProductDes { get; set; }
public int ProductQty { get; set; }
public double ProductRate { get; set; }
public double Inches { get; set; }
public DateTime Date { get; set; }
public int AddCatagoryId { get; set; }
public int AddSubCatagoryId { get; set; }
public virtual AddCatagory tblcatagory{ get; set; }
public virtual AddSubCatagory tblsubcatagory{ get; set; }
}
wepapi controller
public List<Product> Getproducts()
{
var result = db.products.ToList();
return result;
}
angularjs code..
GetAllPro();
function GetAllPro() {
$http.get("/api/Products").then(function (response) {
$scope.Pro = response.data;
}, function () {
alert("Error")
})
}

Cannot get my database-update to work

I have launched my website in beta-version. The next version should contain a shopping cart and a checkout with the credit card. On my way to making this shopping cart, I've discovered that my old Product-class with several different prices simply doesn't work. I need one price with one identity or a subclass with several prices mapped to the original class(which I will use) :
public class Product
{
[Key]
public int ProductID { get; set; }
[Required(ErrorMessage = "Please enter an product name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please specify a category")]
public string Category { get; set; }
public string SubCategory { get; set; }
public string Description { get; set; }
public decimal Price16 { get; set; }
public decimal Price12 { get; set; }
public decimal Price8 { get; set; }
public decimal Price4 { get; set; }
public decimal PriceEach { get; set; }
public decimal PriceKg { get; set; }
public string ProductImageSmallUrl { get; set; }
public string ProductImageSmallAlternativeDescription { get; set; }
public string ProductImageSmallContentType { get; set; }
public string ProductImageLargeUrl { get; set; }
public string ProductImageLargeAlternativeDescription { get; set; }
public string ProductImageLargeContentType { get; set; }
public string ProductImageLargeSecondUrl { get; set; }
public string ProductImageLargeSecondAlternativeDescription { get;
set; }
public string ProductImageLargeSecondContentType { get; set; }
}
I have after, a lot of research constructed two classes:
public class Product
{
public Product(ICollection<Price> prices)
{
Prices = prices;
}
[Key]
public int ProductID { get; set; }
[Required(ErrorMessage = "Please enter an product name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please specify a category")]
public string Category { get; set; }
public string SubCategory { get; set; }
public string Description { get; set; }
public string ProductImageSmallUrl { get; set; }
public string ProductImageSmallAlternativeDescription { get; set; }
public string ProductImageSmallContentType { get; set; }
public string ProductImageLargeUrl { get; set; }
public string ProductImageLargeAlternativeDescription { get; set; }
public string ProductImageLargeContentType { get; set; }
public string ProductImageLargeSecondUrl { get; set; }
public string ProductImageLargeSecondAlternativeDescription { get;
set; }
public string ProductImageLargeSecondContentType { get; set; }
public ICollection<Price> Prices { get; set; }
}
And a price class:
public class Price
{
[Key]
public int ID { get; set; }
public int CurrentProductID { get; set; }
public string Size { get; set; }
public decimal Value { get; set; }
public Product CurrentProduct { get; set; }
}
I have this DbContext:
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<MokaMokkaDbContext>
options)
:base(options) {}
public DbSet<Product> Products { get; set; }
public DbSet<Price> Prices { get; set; }
protected override void OnModelCreating (ModelBuilder modelBuilder)
{
modelBuilder.Entity<Price>()
.HasOne(p => p.CurrentProduct)
.WithMany(b => b.Prices)
.HasForeignKey(p => p.CurrentProductID);
}
}
I am trying to write a seeding class:
public class SeedData
{
public static EnsurePopulated(IApplicationBuilder app)
{
MokaMokkaDbContext context = app.ApplicationServices
.GetRequiredService<MokaMokkaDbContext>();
context.Database.Migrate();
if(!context.Products.Any())
{
context.Products.AddRange(
new Product
{
Name = "Dobos cake",
Category = "Cake",
ProductImageSmallUrl = "Dobos.Torta.jpg",
ProductImageSmallContentType = "jpg",
Prices = new List<Price>()
});
}
}
But I get the following problem in over the red underline of the Product I am trying to create: "There is no argument given that corresponds to the required formal parameter "prices" of Product.Product(ICollection)".
I believe you need parameterless constructor in your Product class.

Entity Framework: Unable to determine the principal end of the relationship. Multiple added entities may have the same primary key

I'm getting this error while updating the model I'm sharing my code, please tell me the best solution for this.
Ticket Detail Class:
public class TicketDetail
{
[Key]
public int TicketDetailId { get; set; }
public int GenericOrderId { get; set; }
public int PartId { get; set; }
public int Quantity { get; set; }
public decimal? CustomerPrice { get; set; }
public string Status { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
public virtual Part Part { get; set; }
public virtual Ticket Ticket { get; set; }
}
OrderDetailClass:
public class OrderDetail
{
[Key]
public int OrderDetailId { get; set; }
public int GenericOrderId { get; set; }
public int PartId { get; set; }
public int Quantity { get; set; }
public decimal? UnitPrice { get; set; }
public string Status { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
public virtual Part Part { get; set; }
public virtual Order Order { get; set; }
}
Order Class:
public class Order : GenericOrder
{
public virtual ICollection<OrderDetail> OrderDetails { get; set; }
}
Ticket Class
public class Ticket : GenericOrder
{
public virtual ICollection<TicketDetail> TicketDetails { get; set; }
}
GenericOrderClass:
public abstract class GenericOrder
{
[Key]
public int GenericOrderId { get; set; }
public string ProcessId { get; set; }
public DateTime Date { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public string Company { get; set; }
public string Phone { get; set; }
public string Message { get; set; }
public decimal Total { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
}
and this is the controller class code
TryUpdateModel(order);
TryUpdateModel(ticket);
try
{
order.Date = DateTime.Now;
ticket.Date = DateTime.Now;
order.ProcessId = DateTime.Now.Ticks.ToString().Substring(12, 6);
ticket.ProcessId = order.ProcessId;
//Add the Order
storeDB.Orders.Add(order);
storeDB.Tickets.Add(ticket);
//Process the order
cart.CreateOrder(order);
cart.CreateTicket(ticket);
// Save all changes
storeDB.SaveChanges();
//return RedirectToAction("Complete",
// new { id = order.QuoteOrderId });
TempData["OrderSuccess"] = "Your order has been submitted successfully with the Process ID " + order.ProcessId;
TempData["OrderId"] = order.GenericOrderId;
TempData["Email"] = order.Email;
return RedirectToAction("Confirm");
}
catch (Exception e)
{
//Invalid - redisplay with errors
ModelState.AddModelError("", e.Message);
return View(order);
}
I have searched internet but couldn't find any solution.
Try saving Order and Ticket and after they are saved add Details to them.

Resources