Inheritance and navigation properties - entity-framework

I have such relations:
class FirstParent {
public SecondParent SecondRecord { get; set; }
}
class SecondParent {
public IEnumerable<FirstParent> FirstRecords { get; set; }
}
class FirstChild1 : FirstParent {
public String StrInFirstChild1{ get; set; }
}
class SecondChild1 : SecondParent {
public String StrInSecondChild1{ get; set; }
}
class FirstChild2 : FirstParent {
public String StrInFirstChild2{ get; set; }
}
class SecondChild2 : SecondParent {
public String StrInSecondChild2{ get; set; }
}
Records related to class FirstChild1 are of type SecondChild1.
Records related to class FirstChild2 are of type SecondChild2.
When I write
var record = from ch in context.FirstParent.OfType<FirstChild1>() select ch.SecondRecord;
in result I also have SecondParent object.
What is happening? How to load SecondChild1 objects?

I found a resolution. I load records from all four tables and do join to collect needed information to anonymous object.

Related

Using LINQ to query nested object in CosmosDB

I'm trying to query on a LicenseId, which is unique and lives in a doubly nested object. I want to return the entire SoftwareOrderEntity object and filter out everything except the result with the matching Id. So far nothing I have tried works due to limitations with Cosmos...
Classes:
public class SoftwareOrderEntity : IUpdateAuditable, IInsertAuditable
{
public string? OrderId { get; set; }
public SoftwareOrderEntityExternalProperties? ExternalProperties { get; set; }
}
public class SoftwareOrderEntityExternalProperties
{
public List<ProductsOnOrder>? ProductsOnOrder { get; set; }
}
public class ProductsOnOrder
{
public string? ProductId { get; set; }
public List<ProductLicenseIds>? ProductLicenseIds { get; set; }
}
public class ProductLicenseIds
{
public string? LicenseId { get; set; }
public string? AssignedEntityId { get; set; }
}
I've tried many variations of LINQ, such as...
SoftwareOrders.Where(x => x.ExternalProperties.ProductsOnOrder.Where(y => y.ProductLicenseIds.Where(z => z.LicenseId.Contains(licenseId)).Count() > 0).Count() > 0);
And
var res = from c in domainContext.SoftwareOrders
from m in c.ExternalProperties.ProductsOnOrder
from x in m.ProductLicenseIds
where x.LicenseId == licenseId
select c;
EDIT: Any() is not supported by cosmos, which is part of the issue

EF Core 5 and FromSqlRaw with inheritance

I want to use a FromSqlRaw query with view models and inheritance between them.
I created two example view models:
public class SummaryVM
{
public int Quantity { get; set; }
public int Value { get; set; }
}
public class DistrictVM : SummaryVM
{
public string DistrictName { get; set; }
}
My DbContext has this content:
public DbSet<SummaryVM> SummaryVMs { get; set; }
public DbSet<DistrictVM> DistrictVMs { get; set; }
...
modelBuilder.Entity<SummaryVM>().HasNoKey();
My query:
return await _context.DistritVMs.FromSqlRaw(query).ToListAsync();
but I get an error:
SqlException: Invalid column name 'Discriminator'. Invalid column name 'DistrictName'
I know this is due to the TPH pattern and I can solve this problem if I do not use inheritance yet how I can use these two tables with inheritance without TPH, please?
SOLUTION
I had to create a base class which is not registered as entity:
public abstract BaseClass
{
public int Quantity { get; set; }
public int Value { get; set; }
}
public class SummaryVM : BaseClass
{
}
public class DistrictVM : BaseClass
{
public string DistrictName { get; set; }
}
SOLUTION
I had to create a base class which is not registered as entity:
public abstract BaseClass
{
public int Quantity { get; set; }
public int Value { get; set; }
}
public class SummaryVM : BaseClass
{
}
public class DistrictVM : BaseClass
{
public string DistrictName { get; set; }
}

Eager loading of derived class in Entity Framework

I have a model like this:
public abstract class Point
{
public int Id { set; get; }
public string Name_F { set; get; }
public byte Side { set; get; }
}
public class Place : Point
{
public bool IsATM { set; get; }
public bool Is24h { set; get; }
public string Tel { set; get; }
public virtual Category Category { set; get; }
}
public class Street : Point
{
public bool IsWalkway { set; get; }
}
I want to load all of the Point table records including records for Place and Street which are derived from Point class.
I used this but I didn't get any data:
var points = Context.Points
.OfType<Place>()
.Include(p => p.SubCategory)
.Concat<Points>(Context.Points.OfType<Street>());
I would like to get Places and Streets in the same query.
Any idea?

AutoMapper is Creating Duplicate Record in DB

It could be very basic question but i have stuck with this
I have an Entity Structure like this one below
public class OrderTagGroup : Entity
{
public virtual string Name { get; set; }
public virtual List<OrderTag> OrderTags { get; set; }
}
public class OrderTag : Entity
{
public virtual string Name { get; set; }
public virtual int? OrderTagGroupId { get; set; }
}
and Its respective DTO is
public class OrderTagGroupDto : EntityDto
{
[Required]
public string Name { get; set; }
public List<OrderTagDto> OrderTags { get; set; }
}
public class OrderTagDto : EntityDto
{
[Required]
public string Name { get; set; }
public int? OrderTagGroupId { get; set; }
}
I have added the Auto mapping as well like this
Mapper.CreateMap<OrderTagGroup, OrderTagGroupDto>();
Mapper.CreateMap<OrderTagGroupDto, OrderTagGroup>();
Mapper.CreateMap<OrderTag, OrderTagDto>();
Mapper.CreateMap<OrderTagDto, OrderTag>();
Here is my Repository update
public void UpdateOrderTagGroup(OrderTagGroupDto OrderTagGroup)
{
var group = _OrderTagGroupRepo.Get(OrderTagGroup.Id);
if (group != null && group.Id > 0)
{
Mapper.Map<OrderTagGroupDto, OrderTagGroup>(OrderTagGroup,group);
}
}
My Question is, whenever my OrderTagGroupDTO goes for the update, it creates a new row in the DB and previous entry is not deleted.
Could you please help me where i am wrong ?
Automapper is for entity->DTO ..
NEVER use automapper or similar for DTO->entity it's NOT designed for that
For DTO->entity you should 'always' do it 'manually'

EF TPT Inheritance: one DbSet per child?

In the MSDN they show how to implement EF TPT with this example:
public abstract class BillingDetail
{
public int BillingDetailId { get; set; }
public string Owner { get; set; }
public string Number { get; set; }
}
[Table("BankAccounts")]
public class BankAccount : BillingDetail
{
public string BankName { get; set; }
public string Swift { get; set; }
}
[Table("CreditCards")]
public class CreditCard : BillingDetail
{
public int CardType { get; set; }
public string ExpiryMonth { get; set; }
public string ExpiryYear { get; set; }
}
public class InheritanceMappingContext : DbContext
{
public DbSet<BillingDetail> BillingDetails { get; set; }
}
Regarding (*) I have this question:
Can I have a DbSet per child in the hierarchy? ie:
public class InheritanceMappingContext : DbContext
{
public DbSet<BankAccount> BankAccount { get; set; }
public DbSet<CreditCard> CreditCards{ get; set; }
}
I'm asking this because I'd like to have a main father class from which all the other classes inherit, ie:
public abstract class DatabaseItem
{
[Key]
public long DatabaseItemId { get; set; }
}
public User : DatabaseItem
{
...
}
public Picture : DatabaseItem
{
...
}
public Gallery : DatabaseItem
{
...
}
So that given an ID, I know that it corresponds to only one thing.
In the past in other projects I didnt do this, and used specifical IDs: "UserId", "PictureId", "GalleryId".
In this case, I will be having only one DbSet?
DbSet<DatabaseItem> DatabaseItems