What is the proper way to show "Admin Tables" in my "Business Objects"? I have the following on my Address object.
public class Address
{
public int AddressID { get; set; }
public KeyValuePair<short, string> County { get; set; }
...
}
Now how would I instantiate this object, as far as the KeyValuePair<,> properties go?
My guess is:
var myAddress = new Address { AddressID = 3, County = new KeyValuePair<short, string>(32, "La Crosse")}
EDIT
This is what I am replacing with the KeyValuePair<> on the recommendations of another Programmer.
.....Address.cs.....
public County County { get; set; }
.....County.cs.....
public class County
{
public short? CountyID { get; set; }
public string CountyName { get; set; }
}
Is there a better way between the two or a third way that is even better?
KeyValuePair<T1, T2> buys you nothing in this case.
Why not just be explicit?
public class Address
{
public int AddressID { get; set; }
public int CountyCode { get; set; }
public string CountyName { get; set; }
}
or another version would be that you define a type County with the two properties, then have a property of that type instead.
In code, clarity is king.
I just ran your code, and it worked as expected.
The country property has correct value Key = 32 and Value = La Crosse.
Your new code is ugly. I'd either remove the setter of the Country property, or make the Country class immutable. This kind of double mutability, is a bug waiting to happen.
Making the Country class immutable, is probably the right decision, since the Id=>Name mapping is fixed.
I'd use:
public class County
{
public short? ID { get; private set; }
public string Name { get; private set; }
private Country(short? id,string name)
{
ID=id;
Name=name;
}
}
Lukazoid gives a good hint why not to do this, bus in fact, the Initialization you are showing would work well. You could have proofen this rather easy using your Debugger. What is the question?
Create a Country object so it is clear what that short and string are supposed to represent.
Related
I am working with AutoMapper, which I am relatively new with, and I stumbled upon a small mapping problem I was hoping the community could assist with.
So I have two data transfer objects:
public class UserDto {
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<CharacterDto> Characters { get; set; }
}
public class CharaterDto {
public string CharacterName { get; set; }
public string ClassName { get; set; }
public int CharacterLevel { get; set; }
}
and two Domain Entities
public class Character {
public int ID { get; set; }
public int UserId { get; set; }
public string CharacterName { get; set; }
public string ClassName { get; set; }
public int CharacterLevel { get; set; }
}
public class User {
public int ID { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
The end goal is to be able to save the data taken in by the DTOs into the database via the Domain Entities; however, when it comes to typing up the list of Characters for 'UserDto', I do not know how to map this properly with AutoMapper. I can map it manually with little to no problems... but I can't find anything that helps to explain this or any examples that would help me understand it better.
I have tried doing things like:
CreateMap<UserDto, Character>()
.ForMember(dest => dest.CharacterName, m => m.MapFrom(source => source.Characters[0].CharacterName));
However, this seems to only map the 1st entry and not the others. I have also considered mapping the individual mappings like so:
CreateMap<CharacterDto, Character>();
CreateMap<UserDto, Character>()
.ForMember(?/*this section I cannot figure out*/)
But can't figure out how to associate the the collection of characters to the mapped CharacterDto. I doubt that if I run the code without that association, the code is going to automatically understand that for each character in characters, map each character using the appropriate mapper... If I must manually do this, I can... but if there is an AutoMapper way, any help constructing it would be greatly appreciated.
Type converters are you friend here for mapping 1 to many like this.
Let me know if you need me to go further and get you a working example from your models.
https://stackoverflow.com/a/18096914/7911333
public String name
{
get;
set;
}
public String email
{
get;
set;
}
public String address
{
get;
set;
}
Is there an easier way to declare multiple variables with same property under one accessibility like this?
Something like
public String name, email, address
{
get;
set;
}
You could package them together in a separate class and then use that as a property:
class Info
{
public String name { get; set; }
public String email { get; set; }
public String address { get; set; }
}
class Person
{
public Info info { get; set; }
}
Obviously it's not what you're after in terms of inlining, but it does present a cleaner option if Info is something you'd use in more than one place. If you're not going to use that class anywhere else, then it's pointless.
Note, as an aside, that I'm using your conventions for capitalization of properties, but it's a "convention" to use Pascal case.
If you don't care for OOP and just want a bunch of strings collected in one variable you can do this with a simple Tuple in your case. It would look like this.
var bunchOfStrings = new Tuple<String,String,String>(String.Empty,String.Empty,String.Empty);
Console.Writeline("{0},{1},{2}",bunchOfStrings.Item1
,bunchOfStrings.Item2
,bunchOfStrings.Item3);
But keep in mind, you hide information with this approach. The items are just numbered and you loose any connection to the semantic of the items.
I am working on building a single family unit (class) for an application. I've done some searching and found solutions for entire family trees, but this app doesn't care about anything outside the single family unit which is defined as (Father, Mother, Child1, Child+n)
This application is about the children (activities they can do based upon age and skill levels), but needs references to the parents. The parents are only needed for reporting purposes and are required to have driver's license and insurance on file.
The application is being built using C# & EF Code First. None of the database annotation elements have been added to the class yet as that isn't the problem.
Below are my classes. The main business rule state that each sibling will have his/her own record, but they need to be linked together so only one mailing (electronic or snail) is sent, if the parents live together. If the parents are divorced, then two letter (or emails) need to be sent.
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Suffix { get; set; }
public string Sex { get; set; }
public DateTime DOB { get; set; }
}
public class Youth : Person
{
public string CurrentGrade { get; set; }
public Adult Mother { get; set; }
public Adult Father { get; set; }
public Adult ICE { get; set; }
public virtual Adult Adult { get; set; }
}
public class Adult : Person
{
public string DriversLicense { get; set; }
public string StateIssued { get; set; }
public string AutoInsuranceCarrier { get; set; }
public string PolicyNumer { get; set; }
public string MaritalStatus { get; set; }
//foreign key
public int VehicleId { get; set; }
public virtual Vehicle Vehicle { get; set; }
}
public class Address
{
public int AddressId { get; set; }
public int PersonId { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public virtual Person Person { get; set; }
}
The logic pattern I was stuck in was that siblings will have the same AddressId. That failed when I applied the divorced parents, each having one child at their address. As far as mailings go, it would work because they are at different addresses. It doesn't feel like the best design. If this were handled by UI, then it would work.
My next thought was to create a Family class and add each family member to it. In this instance, the user would have to make the selection of which people would be living at which address.
public class Family
{
public int FamilyId { get; set; }
public int AddressId { get; set; }
public List<Person> Person;
}
That also doesn't seem like the best solution. I feel there is a better design. I just cannot find it on my own.
Are there any pitfalls to one of these approaches that I'm not seeing yet?
Can someone point me in a better direction? And explain why that direction is better?
Thanks in advance for all your insights!
The "Father", "Youth", "Brother", etc... is not attribute of the person, but attribute of relationship between persons. One person can be both "Father" and "Brother" and "Uncle".
Better design is something like this (i don't know all your requirements):
public class Person {
public Name{get;set;}
// etc...
public List<Relationship> Relationships{get;set;}
}
public class Relationship {
public Person P1{get;set;}
public Person P2{get;set;}
public RelationshipKind Kind{get;set;}
}
public class RelationshipKind {
// for example: Father
public Name1 {get;set;}
// for example: Child
public Name2 {get;set;}
}
Typically you want to keep your models flowing as you would think about them.
For instance, I would not have an Address class that contains Person. I would have an Address class containing only base data about the Address. In Person, I would have an Address. This fits with the "Person lives at this address" and will likely fix your who-lives-where issue. This is the type of setup you have for "Vehicle"
Without going into details regarding whole design, I will focus only on the address issue.
I recommend that you have your address class defined in a way that it does not have navigation property back to a person:
public class Address
{
public int AddressId { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
}
Then I would link your Adult (or even Person) class to Address like so:
public class Adult : Person
{
public string DriversLicense { get; set; }
public string StateIssued { get; set; }
public string AutoInsuranceCarrier { get; set; }
public string PolicyNumer { get; set; }
public string MaritalStatus { get; set; }
//foreign key
public int VehicleId { get; set; }
public virtual Vehicle Vehicle { get; set; }
public int AddressId {get; set;}
public virtual Address Address { get; set; }
}
With this approach, if parents are not divorced, they can share the same address instance. In case they are divorced, your application has to set different address for one of the parents. In case you need to find people living under same address, you can do sth like this:
_dbContext.Persons.Where(p => p.AddressId = addressId) ...
If you have a table of States then you can use that in a lot of places: DriversLicenseState, AddressState, InsuranceState etc. If this isn't a blank string then you don't have to validate the user input and can just put a drop-down on the application.
String current grade. If you instead enter the year the child entered first grade then you don't have to manually update this every year; it can be calculated - though you also have to include an int for NumberOfYearsHeldBack. But its less work to update that int once in a great while, than update every student every year.
Personal Preference: I like 'NameLast' and 'NameFirst' rather than 'FirstName' & 'LastName' just because it means these properties will bunch together alphabetically in all the IDE drop downs etc, just like AddressID, Address1 and Address2
You might consider making 'Mother' into a nullable 'Mother?' and the same with 'Father' to 'Father?'. Some kids simply don't have both parents. If you want to be politically correct you might consider 'Parent1?' and 'Parent2' and put an enum on the relationship to select mother, father, guardian because some kids have 2 moms or 2 dads or their older brother is their legal guardian.
In your address class why is there a person property when you already have a PersonID property? For that matter why does the address have a personID at all? This only needs to be one-way. A person has an address, but an address doesn't have a person. This way you can have 5 people all with the same address. If you try to keep both synchronized two-way it will get fouled up, not to mention you have to have a List<> of personID inside the address. Since address is a type, add another one to each person so you have an AddressPhysical and AddressMailing. Now you can have 4 kids each with different places they sleep but they all get their mail at grandma's P.O.Box.
I wouldn't add a third adult to the child as their ICE. Instead I would make a List<> of adults (its just going to be a list of ID ints really) That way you can keep working down the list in an emergency until you reach someone.
Im want to create a data structure for using within my MVC3 application. The site holds videos uploaded by users, I want to be able of setting up a location for the video so later on you can search based on the country, region or city.
The modeling of those entities is not a big problem to me, my question is which class attribute should I use for my video entity.
public class Country
{
int CountryId
string CountryName
}
public class Region
{
int RegionId
string RegionName
int FK_CountryId
}
public class City
{
int CityId
string CityName
int FK_CountryId
int FK_RegionId
}
........
public class Video
{
int VideoId;
string VideoName;
**Location VideoLocation;**
}
**public class Location
{
int LocationId;
Country CountrId;
Region RegionId;
City CityId;
}**
My initial idea, but I think it is not a really good design since you can have 2 identical rows for a Location, where it should be ideal to keep a unique reference to Locations
What do you think in terms of good design and performance?
That is everyone's nightmare I guess. Well...at least that was my nightmare when designing one of the applications.
Depending on your secenario you might keep countries, cities, regions as different entities. Everything is find with that approach until you want the user to select either country, region or city. Looks like you would need to have nullable fields, which is not really the best practice, because you would then have to fully rely on application logic to maintain data integrity.
Example of that approach would be:
public class Country
{
public string Code { get; set; } //country ID would not make sense in this approach
public string Name { get; set; }
}
public class Region
{
public string Code { get; set; }
public string Name { get; set; }
public string CountryCode { get; set; } //1 region is assigned to only 1 country
}
public class City
{
public string Code { get; set; }
public string Name { get; set; }
public string RegionCode { get; set; } //1 city is assigned to only 1 region
}
It looks good, simple to understand but think about the table where you capture what's been selected. If you only care about city (last item in dependency list), it's all clear and fine.
public class UserSelectionWithCityOnly
{
public string CityCode { get; set; }
}
Pretty easy and straight forward? Looks like it is.
Consider the scenario where you can select either country,city or region....it get's really messy:
public class UserSelectionWithEitherSelected
{
public string? CityCode { get; set; }
public string? RegionCode { get; set; }
public string? CountryCode { get; set; }
}
well...you could always check if CityCode.HasValue, but from DB point of view that would be a nullable field, which can add dirty data (should be fine if you are not pedantic about having neat and clean DB)
So they way I solve this was by creating one hierarchical table with parent item id :
public class MySolutionForDestinations
{
public int DestinationId { get; set; } //primary key
public int ParentDestinationId { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public DestinationLevel Level { get; set; }
}
public enum DestinationLevel
{
Country = 0,
Region = 1,
City = 2
}
it's probably not the most elegant solution, but it works really well. In this approach you only care about DestinationId which can be a country Id, region Id or a city Id, so you would definitely avoid having dirty data and can implement 1 to 1 mapping.
Hope this will be usefull
Given an Employee entity and bunch of personal/organization-related information (like marital status, children information, department, position). Is all personal information to be represented as components/value objects or it is better for the information to reside inside the entity class?
Would using a person (which could gather all personal info) value object as an underlying object (composition) for an Employee entity be a bad design choice?
Also how would such a behaviour modelled properly (in terms of DDD): If employee has kids then it should have a birth certificate (with corresponding data: name, issue date, etc) or If employee is married then it should have marriage certificate (with corresponding data: spouse name, etc)?
For a kids case I decided to use ChildrenInformation value object:
public class ChildrenInformation
{
public String BirthCertificateCode { get;set; }
public DateTime BirthCertificateIssueDate { get;set; }
public ChildName { get; set; }
public ChildMiddleName { get; set; }
public ChildLastName { get; set; }
public DateTime ChildBirthday{ get; set; }
}
public class Employee : AbstractEntity<Employee>, IAggregateRoot
{
public ISet<ChildrenInformation> ChildrenInformation { get; set; }
/* other things ...*/
}
Wouldn't it be wrong from a design view?
EDIT
Another thought is to share Certificate class.
[Serializable]
public class Certificate
{
public String Code { get; set; }
public String Number { get; set; }
public String RegistreeName { get; set; }
public Address RegistreeAddress { get; set; }
public String RegistreeDateOfBirth { get; set; }
public String RegistredAt { get; set; }
public DateTime DateRegistred { get; set; }
}
[Serializable]
public class Employee : AbstractEntity<Employee>, IAggregateRoot
{
public Certificate Passport { get; set; }
public Certificate MarriageCertificate { get; set; }
public ISet<Certificate> ChildrenBirthCertificates { get; set; }
}
Thanks!
I would model it like this:
public class Person
{
public String Name { get; set; }
public String MiddleName { get; set; }
public String LastName { get; set; }
public DateTime Birthday { get; set; }
public BirthCertificate BirthCertificate { get;set; }
public MarriageCertificate MarriageCertificate { get;set; }
// ...etc...
}
public class Certificate
{
public String Code { get;set; }
public DateTime IssueDate { get;set; }
// ...etc...
}
public class BirthCertificate: Certificate
{
public DateTime BirthDate { get;set; }
// ...etc...
}
public class MarriageCertificate: Certificate
{
public String SpouseName { get;set; } // or Spouse could also be a person
// ...etc...
}
public class Employee
{
public ISet<Person> Children { get; }
// ...etc...
}
Some points:
Note the ? usage which means certificates are optional.
Certificate deserve their own types. If you have more than one property that start with the same prefix, most of the time, it means you can define an object off them. I have also created a base Certificate class because they may share some common properties and behavior.
Children is a collection of Person objects.
Spouse could also be a person, if you will (the property would then be named Spouse).
I don't repeat the declaring type name in a property name: Name instead of PersonName
Given an Employee entity and bunch of personal/organization-related information (like marital status, children information, department, position). Is all personal information to be represented as components/value objects or it is better for the information to reside inside the entity class?
I would put all of the given examples as properties in the employee entity. I don't see any benefit in having them as value objects?
Would using a person (which could gather all personal info) value object as an underlying object (composition) for an Employee entity be a bad design choice?
This is more of a domain question. I normally do not use inheritance but use Customer and Employee (instead of a Person entity) as to different models not related to each other.
Please note that the design concept of composition has nothing to do with the CLR concept of a value type. Composition just means that the life-time of the owned object is bound to the life-time of the owner. This can also be achieved with reference types, for example if the owner is the only one with a reference to the owned object.
That said, the solution from Simon is just fine.