EntityFrameworkCore - Classes and Entity distinction - migration

Just been writing up my models and dbcontext using a code first approach for EFCore and i've hit a small problem... specifically with classes and generating migrations.
It seems with entityframework any class is seen as an entity/table (my assumptions so far) but what if I want a class to be a list of fields extended onto my entity?
For example:
public class Person {
public int Id { get; set; }
public string Name { get; set; }
public Address AddressDetails { get; set; }
}
public class Address {
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string City { get; set; }
public string County { get; set; }
public string PostCode { get; set; }
}
How can I mark the address class as additional fields to the person entity as opposed to a separate entity?
Cheers,
Mark

Related

Owned Type in EF Core with optional navigation

Below are My class
class Company
{
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public int? CityId { get; set; }
public City City { get; set; }
public int CountryId { get; set; }
public Country Country { get; set; }
}
public class City
{
public int Id { get; set; }
public string Name { get; set; }
}
My question is:
Can i make Address class as OwnedType because City id is optional
if i make Address as owned type then my City class also need to be owned type?
Thanks in advance a. using ef core 3.1
You can make your Address class as OwnedType like this.
Adress class:
public class Address
{
public string Street { get; set; }
public int? CityId { get; set; }
public City City { get; set; }
public Company Company { get; set; }
}
Company Class:
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
}
Fluent Api:
public class YourDbContext : DbContext
{
public YourDbContext (DbContextOptions<YourDbContext> options)
: base(options)
{
}
//Note:no need add Address DbSet
public DbSet<City> City { get; set; }
public DbSet<Company> Company { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Company>().OwnsOne(c => c.Address);
}
}
if i make Address as owned type then my City class also need to be owned type?
Your City class don't need to be owned type.
Reference:
https://learn.microsoft.com/en-us/ef/core/modeling/owned-entities#explicit-configuration
Result:
When you configure owned type,this make company and address generate one table and the city id could either be set or not.And if you want to set the city id,you need to insert a new record in your city table.

Doubts about EF Core 2.1 Relations

I am working on Entity Framework Core Code First approach and ASP.Net Core 2.1 making 3 tables:
Person class
public class Person
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public PeopleProfessions PeopleProfessions { get; set; }
}
Professions' class
public class Profession
{
public string Id { get; set; }
public string Name{ get; set; }
public PeopleProfessions PeopleProfessions { get; set; }
}
peopleprofessions' class
public class peopleprofessions
{
[ForeignKey("PersonId ")]
public string PersonId { get; set; }
public ICollection<Person> People { get; set; }
[ForeignKey("ProfessionId")]
public string ProfessionId{ get; set; }
public ICollection<Profession> Professions { get; set; }
}
On my Context:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<peopleprofessions>().HasKey(up => new { up.PersonId, up.ProfessionId });
}
Bearing this in mind:
People can have multiple professions.
The professions table is only for reading stored data like "Accountant".
I have doubts about how I can make table 3 only contain the foreigners and that it can meet the needs that I just mentioned.
I have tried to make the relationship appropriately but I also noticed that in tables 1 and 2 it requests both Id of the table people's professions.
I don't know if I am lost or if I am looking wrong or if there is an alternative to that situation. Thanks for any help you can give me.
You have the use of Collections on the navigation items a bit backwards. For your primary entities (Person and Profession), they should have collections, since it's one-to-many. But for the PeopleProfessions, each record is a single link to a specific entity, so no collection there just a direct object reference.
public class Person
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<PeopleProfessions> PeopleProfessions { get; set; }
}
public class Profession
{
public string Id { get; set; }
public string Name{ get; set; }
public ICollection<PeopleProfessions> PeopleProfessions { get; set; }
}
public class PeopleProfessions
{
public string PersonId { get; set; }
public Person Person { get; set; }
public string ProfessionId { get; set; }
public Profession Profession { get; set; }
}
You can, but don't need to specify a ForeignKey attribute because you are following EFs naming conventions(it will figure it out for you). Your OnModelCreating looks correct for the composite key.
You may want to consider removing the plural from PeopleProfessions (just call the class PeopleProfession) since one instance represents a single People-Profession relationship. I typically do this and but the navigation name in the entities remains plural, since it can represent more than one, i.e.
public ICollection<PeopleProfession> PeopleProfessions { get; set; }

Automapper and EF Navigation Properties

With ASP.NET MVC Core and Entity Framework Core I'm trying to create a simple website.
I've defined my Model:
public class Club
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual IEnumerable<Team> Teams { get; set; }
}
public class Team
{
[Key]
public int Id { get; set; }
public int ClubId { get; set; }
[MaxLength(32)]
public string Name { get; set; }
public virtual Club Club { get; set; }
}
As well as the corresponding View Models:
public class ClubViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public virtual IEnumerable<TeamViewModel> Teams { get; set; }
}
public class TeamViewModel
{
public int Id { get; set; }
public int ClubId { get; set; }
public string Name { get; set; }
public virtual ClubViewModel Club { get; set; }
}
I've defined an Automapper Profile with the corresponding mappers:
CreateMap<Club, ClubViewModel>();
CreateMap<ClubViewModel, Club>();
CreateMap<Team, TeamViewModel>();
CreateMap<TeamViewModel, Team>();
I try to load a Club entity, with the navigation property Teams included (_context.Club.Include(c => c.Teams).ToList()). This works as expected, it returns a Club with a list of Teams. But when I try to map this instance to a ClubViewModel, I get an 502.3 error and my debug session is ended immediately.
It seems like I am missing something trivial, but I simply do not see it. There's no information in the Windows Event Log and I can't find any usefull information in the IIS Express logging (%userprofile%\documents\IISExpress)
What is causing the crash?
You can't perform this mapping because it is circular. You'll have to remove this line
public virtual ClubViewModel Club { get; set; }
from your TeamViewModel and the mapping should work as expected.

Ouerying an object inside ravendb document

There is a doubt as of how to query or retrieve a value from an object stored in an document as follows in raven db.
class User
{
public String Id { get; set; }
public AccountType AccountType { get; set; }Servicetax
public String MainAccountMobileNo { get; set; }
public UserStatus Status { get; set; }
public String EmailId { get; set; }
public String DisplayName { get; set; }
public Object User { get; set; }
}
Here i am storing three different types of classes into the object User.
Say Customer,Retailer and Trader.
Customer
{
public String Name{ get; set; }
public String Address { get; set; }
public String MobileNo { get; set; }
public String EmailId { get; set; }
}
Retailer
{
public String Name{ get; set; }
public String Address { get; set; }
public String MobileNo { get; set; }
public String EmailId { get; set; }
}
Trader
{
public String Name{ get; set; }
public String Address { get; set; }
public String MobileNo { get; set; }
public String EmailId { get; set; }
}
Now is it possible to retrieve results based on the Customer's class detail?
That is now i want to retrieve All the Customers based on Address in the customer class, So how will i do it? How to typecast the object user in the query to type customer.
Thanks.
The user object in the document can store any type of class's object like account info trader in the above image. So how can i query from the object type that cannot is not definite and changing.
var Result = sess.Query<UserAccountInfo>().Where(x => x.AccountType == usertype && ((AccountInfoCustomer)x.User).Customerstatus == CustomerStatus.Pending);
This is the query that's been tried and this is the exception that's been caught
{"Url:
\"/indexes/dynamic/UserAccountInfos?query=AccountType%253ADistributor%2520AND%2520User).Customerstatus%253APending&start=0&pageSize=128&aggregation=None\"\r\n\r\nSystem.ArgumentException:
The field ')_Customerstatus' is not indexed, cannot query on fields
that are not indexed\r\n at
Raven.Database.Indexing.Index.IndexQueryOperation.AssertQueryDoesNotContainFieldsThatAreNotIndexes()
The problem here was the build of raven db. i was using the older build after changing it to newer version the query
var Result = sess.Query<UserAccountInfo>().Where(x => x.AccountType == usertype && ((AccountInfoCustomer)x.User).Customerstatus == CustomerStatus.Pending);
works fine.
Your classes are not very DRY. Consider this instead:
public abstract class Person
{
public string Name{ get; set; }
public string Address { get; set; }
public string MobileNumber { get; set; }
public string EmailAddress { get; set; }
}
public class Customer : Person {}
public class Retailer : Person {}
public class Trader : Person {}
Then, in your User class replace
public Object User { get; set; }
With this:
public Person Person { get; set; }
That way, you can store an instance of any of the 3 derived types. I wouldn't call the property User given that the containing class is called User and User.User could get confusing to anyone having to understand your code.

Fluent nHIbernate - Map a referenced / embedded class to same table as parent

I have a flat view that consists of columns such as:
ResultID
ResultName
ResultTime
DisciplineCode
DisciplineName
DateModified
etc...
I have a Result class that currently matches the above schema (flat)
public class Result
{
public virtual string ResultID { get; set; }
public virtual string ResultName { get; set; }
public virtual decimal ResultTime { get; set; }
public virtual string DisciplineCode { get; set; }
public virtual string DisciplineName { get; set; }
public virtual DateTime DateModified { get; set; }
}
What I'd like, is to separate my Discipline properties into their own class like this:
public class Discipline
{
public virtual string DisciplineCode { get; set; }
public virtual string DisciplineName { get; set; }
}
And then change my Result class to:
public class Result
{
public virtual string ResultID { get; set; }
public virtual string ResultName { get; set; }
public virtual decimal ResultTime { get; set; }
public virtual Discipline Discipline { get; set; }
public virtual DateTime DateModified { get; set; }
}
So that the Discipline is embedded as a class.
The details come from the same table (or in my case, normalized view)
How can I map this with fluent nHibernate
I've looked at References, but not sure if that's right?
Component sorted this.
Didn't realize I'd actually asked this question already a few days ago (in a different form)
See my answer here - https://stackoverflow.com/a/11397884/131809