I have two entities and their relationship is many to many. The code is like below:
public class Post : Entity
{
//public int Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public DateTime CreateTime { get; set; }
public DateTime LastModify { get; set; }
public ICollection<PostTag> PostTags { get; set; }
public int AuthorId { get; set; }
public Author Author { get; set; }
}
public class Tag :Entity
{
//public int Id { get; set; }
public string TagName { get; set; }
public ICollection<PostTag> PostTags { get; set; }
}
public class PostTag :Entity
{
//public int Id { get; set; }
public int PostId { get; set; }
public Post Post { get; set; }
public int TagId { get; set; }
public Tag Tag { get; set; }
}
public class PostViewModel
{
public string Title { get; set; }
public string Body { get; set; }
public DateTime CreateTime { get; set; }
public DateTime LastModify { get; set; }
public int AuthorId { get; set; }
public string AuthorName { get; set; }
public List<TagViewModel> Tags { get; set; }
}
Now, I had created the mapping configure from entity to viewmodel:
CreateMap<Post, PostViewModel>()
.ForMember(dest => dest.AuthorId, opt => opt.MapFrom(src => src.Author.Id))
.ForMember(dest => dest.Tags, opt => opt.MapFrom(src => src.PostTags))
.ForMember(dest => dest.AuthorName, opt => opt.MapFrom(src => src.Author.User.LastName))
.ForMember(dest => dest.Body, opt => opt.MapFrom(src => src.Body))
.ForMember(dest => dest.Title, opt => opt.MapFrom(src => src.Title))
.ForMember(dest => dest.CreateTime, opt => opt.MapFrom(src => src.CreateTime))
.ForMember(dest => dest.LastModify, opt => opt.MapFrom(src => src.LastModify))
.ForMember(dest => dest.Tags, opt => opt.MapFrom(src => src.PostTags.Select(y => y.Tag).ToList()));
My question is, when I receive a PostViewModel like:
public async Task<IActionResult> Post([FromBody] PostViewModel postViewModel)
{
}
how can I map the PostViewModel to Post? And I want to create an Entity from the PostViewModel and add them, which is post, tag(if not exist) and postTag relationship, into DbContext, what should I do?
I am pretty new to automapper and this is my first question, I hope I am doing right thing and I really appreciate your answer and guid for how to ask.
You have two choices I think.
1) Reverse mapping
You can just add .ReverseMap() to the end of your mapping config
CreateMap<Post, PostViewModel>()
.ForMember(dest => dest.AuthorId, opt => opt.MapFrom(src => src.Author.Id))
...
.ForMember(dest => dest.Tags, opt => opt.MapFrom(src => src.PostTags.Select(y => y.Tag).ToList()))
.ReverseMap();
2) You can define a new configuration for PostViewModel to Post
CreateMap<PostViewModel, Post>()
.ForMember(dest => dest.Author.Id, opt => opt.MapFrom(src => src.AuthorId))
...etc
Then Mapper.Map<Post>(postViewModel)
Related
I basically have three tables that I need to query information to get PersonNotes. I am using Entity Framwork Core 3.
Person Table
PersonNote Table
PersonNoteAttachment Table
One person can have many personnotes and one personnote can contain many PersonNoteAttachment.
I need Person table to get the FirstName and LastName which is mapped to the AuthorName in the PersonNote User data model. You can see the mapping section which shows the mapping.
DataModels
namespace Genistar.Organisation.Models.DataModels
{
[Table(nameof(PersonNote), Schema = "common")]
public class PersonNote
{
public int Id { get; set; }
public int PersonId { get; set; }
[ForeignKey("PersonId")]
public Person Person { get; set; }
public string Note { get; set; }
public int AuthorId { get; set; }
[ForeignKey("AuthorId")]
public Person Author { get; set; }
public string CreatedBy { get; set; }
public DateTime Created { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime RecordStartDateTime { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime RecordEndDateTime { get; set; }
}
}
namespace Genistar.Organisation.Models.DataModels
{
[Table(nameof(PersonNoteAttachment), Schema = "common")]
public class PersonNoteAttachment
{
public int Id { get; set; }
public int PersonNoteId { get; set; }
[ForeignKey("PersonNoteId")]
public PersonNote PersonNote { get; set; }
public string Alias { get; set; }
public string FileName { get; set; }
public string MimeType { get; set; }
public int Deleted { get; set; }
public string CreatedBy { get; set; }
public DateTime Created { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime RecordStartDateTime { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime RecordEndDateTime { get; set; }
}
}
User Model - This is the model that I am returning to the client application
namespace Genistar.Organisation.Models.User
{
[Table(nameof(PersonNote), Schema = "common")]
public class PersonNote
{
public int Id { get; set; }
public int PersonId { get; set; }
public string Note { get; set; }
public int AuthorId { get; set; }
public string AuthorName { get; set; }
public string CreatedBy { get; set; }
public DateTime Created { get; set; }
}
}
Mapping
CreateMap<Genistar.Organisation.Models.DataModels.PersonNote, Genistar.Organisation.Models.User.PersonNote>()
.ForMember(t => t.Id, opt => opt.MapFrom(s => s.Id))
.ForMember(t => t.PersonId, opt => opt.MapFrom(s => s.PersonId))
.ForMember(t => t.AuthorName, opt => opt.MapFrom(s => s.Author.FirstName + " " + s.Author.LastName))
.ForMember(t => t.Note, opt => opt.MapFrom(s => s.Note))
.ForMember(t => t.AuthorId, opt => opt.MapFrom(s => s.AuthorId))
.ForMember(t => t.CreatedBy, opt => opt.MapFrom(s => s.CreatedBy))
.ForMember(t => t.Created, opt => opt.MapFrom(s => s.Created));
The following query works but is only pulling data from Person and PersonNote table. I am looking at getting the PersonNoteAttachment as well. How do I do that ? I would basically need FileName & MimeType
field populated in User.PersonNote model. If you see above I have created a PersonNoteAttachment data model
Repository
public IQueryable<PersonNote> GetPersonNotes(int personId)
{
var personNotes = _context.PersonNotes.Include(x => x.Person).Include(x=> x.Author).Where(p => p.PersonId == personId);
return personNotes;
}
API :
[FunctionName(nameof(GetPersonNote))]
[UsedImplicitly]
public Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "person-note/{id}")] HttpRequest req,
int id) => _helper.HandleAsync(async () =>
{
//await _helper.ValidateRequestAsync(req, SecurityPolicies.ViewNotes);
var personNotes = await _organisationRepository.GetPersonNotes(id).ProjectTo<PersonNote>(_mapper.ConfigurationProvider).ToListAsync();
return new OkObjectResult(personNotes);
});
My approach was to do it the following way in the repository but I need to return the PersonNote datamodel in the repository. I cannot add those additional fields in the model because it say invalid columns.How do I approach this ?
var personNotes = _context.PersonNotes
.Include(x => x.Person)
.Include(x => x.Author)
.Where(p => p.PersonId == personId)
.Join(_context.PersonNotesAttachments, c => c.Id, cm => cm.PersonNoteId, (c, cm) => new
{
cm.PersonNote.Id,
cm.PersonNote.PersonId,
cm.PersonNote.Person,
cm.PersonNote.Note,
cm.FileName,
cm.MimeType,
cm.Alias,
cm.PersonNote.AuthorId,
cm.PersonNote.CreatedBy,
cm.PersonNote.Created
});
I have resolved the issue
I just had to add the following line in PersonNote datamodel
public PersonNoteAttachment PersonNoteAttachment { get; set; }
Added the new fields to the PersonNote usermodel and did the following mapping
.ForMember(t => t.FileName, opt => opt.MapFrom(s => s.PersonNoteAttachment.FileName))
.ForMember(t => t.MimeType, opt => opt.MapFrom(s => s.PersonNoteAttachment.MimeType))
.ForMember(t => t.Alias, opt => opt.MapFrom(s => s.PersonNoteAttachment.Alias))
Given the following entity models:
public class Workshop
{
public Guid Id { get; set; }
public string Name { get; set; }
public ICollection<QuoteRequest> QuoteRequests { get; set; }
}
public class QuoteRequest
{
public Guid Id { get; set; }
public Guid CustomerId { get; set; }
public Guid WorkshopId { get; set; }
public bool Responded { get; set; }
public decimal? Amount { get; set; }
public virtual Customer Customer { get; set; }
public virtual Workshop Workshop { get; set; }
}
and the following 2 view models:
public class WorkshopModel
{
public Guid Id { get; set; }
public string Name { get; set; }
public ICollection<QuoteRequestModel> QuoteRequests { get; set; }
}
public class QuoteRequestModel
{
public Guid Id { get; set; }
public Guid CustomerId { get; set; }
public Guid WorkshopId { get; set; }
public bool Responded { get; set; }
public decimal? Amount { get; set; }
public CustomerModel Customer { get; set; }
public WorkshopModel Workshop { get; set; }
}
Next, given the following query:
public async Task<Workshop> GetWorkshopAsync(Guid id, bool includeQuotes = false)
{
IQueryable<Workshop> query = _context.Workshops;
if (includeQuotes)
{
query = query.Include(w => w.QuoteRequests);
}
return await query.FirstOrDefaultAsync(w => w.Id == id);
}
No matter what I do, I cannot get EF to not give me a circular relationship when querying a Workshop. For instance, I query one Workshop that has 14 QuoteRequests, each of which has a Workshop, each of which has 14 QuoteRequests etc. etc. :
I do have the json serializer reference loophandling setting set to ignore, but that's not giving me the desired result
services.AddControllers()
.AddNewtonsoftJson(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
I want to thus strip out this circle in my mapping profile. I am using automapper. I have managed to break the circular reference with my mapping profile from the QuoteRequest side:
CreateMap<QuoteRequestModel, QuoteRequest>()
.ForMember(dest => dest.Customer, opt => opt.MapFrom(src => src.Customer))
.ForMember(dest => dest.Workshop, opt => opt.MapFrom(src => src.Workshop))
.ForPath(dest => dest.Customer.QuoteRequests, opt => opt.MapFrom(src => new List<QuoteRequest>()))
.ForPath(dest => dest.Workshop.QuoteRequests, opt => opt.MapFrom(src => new List<QuoteRequest>()));
CreateMap<QuoteRequest, QuoteRequestModel>()
.ForMember(dest => dest.Customer, opt => opt.MapFrom(src => src.Customer))
.ForMember(dest => dest.Workshop, opt => opt.MapFrom(src => src.Workshop))
.ForPath(dest => dest.Customer.QuoteRequests, opt => opt.MapFrom(src => new List<QuoteRequestModel>()))
.ForPath(dest => dest.Workshop.QuoteRequests, opt => opt.MapFrom(src => new List<QuoteRequestModel>()));
This might be a bit of a jank solution, but it's working for now when I query an individual QuoteRequest. What I want to figure out is how to do the same in the mapping profile, from the Workshop side:
CreateMap<WorkshopModel, Workshop>()
.ForMember(dest => dest.QuoteRequests, opt => opt.MapFrom(src => src.QuoteRequests));
CreateMap<Workshop, WorkshopModel>()
.ForMember(dest => dest.QuoteRequests, opt => opt.MapFrom(src => src.QuoteRequests));
I can't really target each iteration of the QuoteRequests to set the Workshop a default value.
This is not an issue. What you're seeing is EF's object fix-up. Because it already has these entities in its object cache, it automatically "fixes up" the relationships on each entity, without querying anything again.
The only time this might be an issue is during serialization, as serializing will attempt to recursively drill-down indefinitely. However, depending on the serialization method, there's different ways to prevent such recursive serialization. Additionally, you should really not serialize entities, directly, anyways. Instead, you should map them over into DTO classes, where you would then define a more basic structure that wouldn't suffer from the same recursive issues. Then, you would serialize the DTO, rather than the entity.
Note: I never solved this issue and just moved on to using a straight up Linq query. .Select(a => new UserDetailsDto { ContactId = a.ContactId, etc
The issue I'm having is trying to understand how Automapper can be used to map navigation properties with the parent entity all in one query.
Lets say I have a UserDto that closely mirrors the entity and looks like this:
public class User
{
public int UserId { get; set; }
public int UserDetailsId { get; set; }
public int ContactId { get; set; }
public DateTime CreateDateTime { get; set; }
public DateTime? ModifiedDateTime { get; set; }
public DateTime? InactiveDateTime { get; set; }
public UserDetail UserDetails { get; set; }
}
Then I have an entity called UserDetail which is mostly made up of navigation properties(I'll post just a few props to keep it short):
public partial class UserDetail
{
public int UserDetailId { get; set; }
public int UsertId { get; set; }
public DateTime? DateOfBirth { get; set; }
public int? ProviderId { get; set; }
public int? FacilityId { get; set; }
public int? CarrierId { get; set; }
public int? GenderId { get; set; }
public int? EthnicityId { get; set; }
}
Then its DTO
public class UserDetailDto
{
public int ParticipantDetailId { get; set; }
public int ParticipantId { get; set; }
public DateTime DateOfBirth { get; set; }
public string Provider { get; set; }
public string Facility { get; set; }
public string Carrier { get; set; }
public string Gender { get; set; }
public string Ethnicity { get; set; }
}
I've seen that you can use something like:
IEnumerable<UserDto> users = await
db.DbContext.Set<User>()
.ProjectTo<UserDto>()
.ToListAsync();
but I don't get how you use that in combination with something like .ForMember in the Mapper Config.
I'm just showing what I've seen. I'm totally open to any suggestion on how to accomplish this.
Edit:
Mapper Config:
config.CreateMap<User, UserDto>();
config.CreateMap<UserDto, User>();
config.CreateMap<UserDetail, UserDetailDto>()
.ForMember(dto => dto.Provider, conf => conf.MapFrom(entity => entity.Provider.ProviderName))
.ForMember(dto => dto.Facility, conf => conf.MapFrom(entity => entity.Facility.FacilityName))
.ForMember(dto => dto.Carrier, conf => conf.MapFrom(entity => entity.Carrier.CarrierName))
.ForMember(dto => dto.Gender, conf => conf.MapFrom(entity => entity.Gender.GenderText))
.ForMember(dto => dto.Ethnicity, conf => conf.MapFrom(entity => entity.Ethnicity.EthnicityText))
.ForMember(dto => dto.Orientation, conf => conf.MapFrom(entity => entity.Orientation.OrientationText))
.ForMember(dto => dto.Education, conf => conf.MapFrom(entity => entity.Education.EducationText))
.ForMember(dto => dto.Employment, conf => conf.MapFrom(entity => entity.Employment.EmploymentText))
.ForMember(dto => dto.EarningRange, conf => conf.MapFrom(entity => entity.EarningRange.EarningRangeText))
.ForMember(dto => dto.Language, conf => conf.MapFrom(entity => entity.Language.LanguageCode))
.ForMember(dto => dto.CallTimeId, conf => conf.MapFrom(entity => entity.CallTime.CallTimeText));
config.CreateMap<ParticipantDetailDto, ParticipantDetail>();
config.CreateMap<UserDetailDto, UserDetail>();
Other people have asked this question and I checked to see if I was making the same errors, and it appears I am not, from what I can tell.
Here is my FollowerMenuItemMerchant class.
public class FollowerMenuItemMerchant
{
[key, Column(Order = 0)]
public int FollowerID { get; set; }
[key, Column(Order = 1)]
public int MenuItemID { get; set; }
[key, Column(Order = 2)]
public int MerchantID { get; set; }
public virtual Follower Follower { get; set; }
public virtual MenuItem MenuItem { get; set; }
public virtual Merchant Merchant { get; set; }
}
And here is the Context class:
public class FlavorPingContext : IdentityDbContext<ApplicationUser>
{
public FlavorPingContext() : base("name=FlavorPingContext")
{
}
public System.Data.Entity.DbSet<FlavorPing.Models.Merchant> Merchants { get; set; }
public System.Data.Entity.DbSet<FlavorPing.Models.MenuItem> MenuItems { get; set; }
public System.Data.Entity.DbSet<FlavorPing.Models.MerchantDetails> MerchantDetails { get; set; }
public System.Data.Entity.DbSet<FlavorPing.Models.Follower> Followers { get; set; }
public System.Data.Entity.DbSet<FlavorPing.Models.FollowerMenuItemMerchant> FollowerMenuItemMerchants { get; set; }
protected override void OnModelCreating(DbModelBuilder builder) {
// Primary keys
builder.Entity<Follower>().HasKey(q => q.FollowerID);
builder.Entity<MenuItem>().HasKey(q => q.MenuItemID);
builder.Entity<Merchant>().HasKey(q => q.MerchantID);
builder.Entity<FollowerMenuItemMerchant>().HasKey(q =>
new {
q.FollowerID, q.MenuItemID, q.MerchantID
});
// Relationships
builder.Entity<FollowerMenuItemMerchant>()
.HasRequired(t => t.Follower)
.WithMany(t => t.FollowerMenuItemMerchants)
.HasForeignKey(t => t.FollowerID);
builder.Entity<FollowerMenuItemMerchant>()
.HasRequired(t => t.MenuItem)
.WithMany(t => t.FollowerMenuItemMerchants)
.HasForeignKey(t => t.MenuItemID);
builder.Entity<FollowerMenuItemMerchant>()
.HasRequired(t => t.Merchant)
.WithMany(t => t.FollowerMenuItemMerchants)
.HasForeignKey(t => t.MerchantID);
}
}
Can you see where there may be an error?
Yikes, I found it! I used lower case "key", and not uppercase "Key"! Doh!
I use Code First EF 5.0 on >Net 4.0 and I has 2 class:
public partial class Kennel
{
public Kennel()
{
this.Brands = new List<Brand>();
this.Dogs = new List<Dog>();
this.Breeds = new List<Breed>();
this.Owners = new List<Person>();
this.Name1 = new KennelName();
this.Name2 = new KennelName();
}
public int ID { get; set; }
public /*DogClub*/int Type { get; set; }
public KennelName Name1 { get; set; }
public KennelName Name2 { get; set; }
public string CertificateNumber { get; set; }
public System.DateTime? AssigmentDate { get; set; }
public string Folder { get; set; }
public string Comment { get; set; }
public int StatusID { get; set; }
public int? FederationID { get; set; }
public int? MainOwnerID { get; set; }
public int? MainBreedID { get; set; }
public virtual ICollection<Brand> Brands { get; set; }
public virtual ICollection<Dog> Dogs { get; set; }
public virtual Breed MainBreed { get; set; }
public virtual Federation Federation { get; set; }
public virtual Status Status { get; set; }
public virtual Person MainOwner { get; set; }
public virtual ICollection<Breed> Breeds { get; set; }
public virtual ICollection<Person> Owners { get; set; }
}
public partial class Breed
{
public Breed()
{
this.Dogs = new List<Dog>();
this.ExpertKerungs = new List<ExpertKerung>();
this.Hallmarks = new List<Hallmark>();
this.Colors = new List<Color>();
this.ExpertBreeds = new List<ExpertBreed>();
this.Kennels = new List<Kennel>();
this.MainKennels = new List<Kennel>();
}
public int ID { get; set; }
public string FciNumber { get; set; }
public string Name { get; set; }
public int BreedGroupID { get; set; }
public bool IsKerung { get; set; }
public string NameLat { get; set; }
public string NativeName { get; set; }
public int CountryID { get; set; }
public System.DateTime? StandardDate { get; set; }
public bool IsCACIB { get; set; }
public bool IsWork { get; set; }
public virtual BreedGroup BreedGroup { get; set; }
public virtual ICollection<Dog> Dogs { get; set; }
public virtual ICollection<ExpertKerung> ExpertKerungs { get; set; }
public virtual ICollection<Hallmark> Hallmarks { get; set; }
public virtual ICollection<Color> Colors { get; set; }
public virtual Country Country { get; set; }
public virtual ICollection<ExpertBreed> ExpertBreeds { get; set; }
public virtual ICollection<Kennel> Kennels { get; set; }
public virtual ICollection<Kennel> MainKennels { get; set; }
}
and mapping:
public class KennelMap : EntityTypeConfiguration<Kennel>
{
public KennelMap()
{
// Primary Key
this.HasKey(t => t.ID);
// Properties
//this.Property(t => t.Name1.Name)
// .IsRequired();
//this.Property(t => t.Name1.IntlName)
// .IsRequired();
//this.Property(t => t.Name2.Name)
// .IsRequired();
//this.Property(t => t.Name2.IntlName)
// .IsRequired();
// Table & Column Mappings
this.ToTable("Kennels");
this.Property(t => t.ID).HasColumnName("ID");
this.Property(t => t.Type).HasColumnName("Type");
this.Property(t => t.Name1.Name).HasColumnName("Name1_Name");
this.Property(t => t.Name1.IntlName).HasColumnName("Name1_IntlName");
this.Property(t => t.Name1.Type).HasColumnName("Name1_Type");
this.Property(t => t.Name1.Approved).HasColumnName("Name1_Approved");
this.Property(t => t.Name2.Name).HasColumnName("Name2_Name");
this.Property(t => t.Name2.IntlName).HasColumnName("Name2_IntlName");
this.Property(t => t.Name2.Type).HasColumnName("Name2_Type");
this.Property(t => t.Name2.Approved).HasColumnName("Name2_Approved");
this.Property(t => t.CertificateNumber).HasColumnName("CertificateNumber");
this.Property(t => t.AssigmentDate).HasColumnName("AssigmentDate");
this.Property(t => t.Folder).HasColumnName("Folder");
this.Property(t => t.Comment).HasColumnName("Comment");
this.Property(t => t.StatusID).HasColumnName("StatusID");
this.Property(t => t.FederationID).HasColumnName("FederationID");
this.Property(t => t.MainOwnerID).HasColumnName("MainOwnerID");
// Relationships
this.HasMany(t => t.Owners)
.WithMany(t => t.Kennels)
.Map(m =>
{
m.ToTable("OwnerKennel");
m.MapLeftKey("Kennels_ID");
m.MapRightKey("Owners_ID");
});
this.HasOptional(t => t.MainBreed)
.WithMany(t => t.MainKennels)
.HasForeignKey(d => d.MainBreedID);
this.HasOptional(t => t.Federation)
.WithMany(t => t.Kennels)
.HasForeignKey(d => d.FederationID);
this.HasRequired(t => t.Status)
.WithMany(t => t.Kennels)
.HasForeignKey(d => d.StatusID);
this.HasOptional(t => t.MainOwner)
.WithMany(t => t.MainKennels)
.HasForeignKey(d => d.MainOwnerID)
.WillCascadeOnDelete(false);
}
}
If I write next code:
int breedID = 1; // some value
Breed br = _kennel.Breeds.FirstOrDefault(t => t.ID == breedID);
if (br != null)
{
_kennel.MainBreed = br;
// but: _kennel.MainBreedID != br.ID
}
OR:
int breedID = 1; // some value
Breed br = _kennel.Breeds.FirstOrDefault(t => t.ID == breedID);
if (br != null)
{
_kennel.MainBreedID = breedID;
// but: _kennel.MainBreed != br
}
Why EF doesnt update navigation property? I set ProxyCreationEnabled and AutoDetectChangesEnabled, but this not work.
See another example of sample code (it accurately reflects my real application code):
Kennel kennel = ctx.Kennels.Add(ctx.Kennels.Create());
kennel.Name1.Name = "Test Kennel";
List<Breed> breeds = ctx.Breeds.Include(b => b.BreedGroup).OrderBy(t => t.BreedGroupID).Where(t => t.ID == 755 || t.ID == 772).ToList();
foreach (var b in breeds)
kennel.Breeds.Add(b);
if (breeds.Count > 0)
{
kennel.MainBreed = breeds[0];
foreach (var k in kennel.MainBreed.MainKennels)
System.Diagnostics.Debug.WriteLine("MainKennel: " + k.Name1.Name);
ctx.ChangeTracker.DetectChanges();
//System.Diagnostics.Debug.WriteLine("MainBreed: " + kennel.MainBreed);
System.Diagnostics.Debug.WriteLine("MainBreedID: " + kennel.MainBreedID);
}
After call to DetectChanges all navigation properties and collection reflect changes (kennel.MainBreedID != null).
Try making all your POCO properties virtual rather than just the navigation properties. This will allow EF to create change tracking proxies rather than lazy loading proxies. I've not tested this, but you may then get the behavior that you expect.
Remove the intialisation of the collections from the constructor
//this.Dogs = new List<Dog>();
//this.ExpertKerungs = new List<ExpertKerung>();
//this.Hallmarks = new List<Hallmark>();
//this.Colors = new List<Color>();
//this.ExpertBreeds = new List<ExpertBreed>();
//this.Kennels = new List<Kennel>();
//this.MainKennels = new List<Kennel>();