C# Family Class Design
Я работаю над созданием единого семейного блока (класса) для приложения. Я провел поиск и нашел решения для целых родословных, но это приложение не заботится ни о чем, кроме единственной семейной единицы, которая определяется как (Отец, Мать, Ребенок1, Ребенок +n)
Это приложение о детях (действия, которые они могут выполнять в зависимости от возраста и уровня навыков), но для этого нужны ссылки на родителей. Родители нужны только для целей отчетности и должны иметь водительские права и страховку в архиве.
Приложение создается с использованием C# и EF Code First. Ни один из элементов аннотации базы данных еще не добавлен в класс, поскольку это не проблема.
Ниже приведены мои занятия. Основное бизнес-правило гласит, что у каждого родного брата будет своя собственная запись, но их необходимо связать вместе, чтобы отправлялась только одна электронная почта (электронная или обычная), если родители живут вместе. Если родители разведены, то необходимо отправить два письма (или электронные письма).
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; }
}
Логическая схема, в которой я застрял, заключалась в том, что у братьев и сестер будет одинаковый AddressId. Это не удалось, когда я обратился к разведенным родителям, у каждого из которых по одному адресу. Что касается рассылок, это будет работать, потому что они находятся по разным адресам. Это не лучший дизайн. Если бы это было обработано пользовательским интерфейсом, то это сработало бы.
Моей следующей мыслью было создать класс Family и добавить в него каждого члена семьи. В этом случае пользователь должен будет выбрать, какие люди будут жить по какому адресу.
public class Family
{
public int FamilyId { get; set; }
public int AddressId { get; set; }
public List<Person> Person;
}
Это также не кажется лучшим решением. Я чувствую, что есть лучший дизайн. Я просто не могу найти это самостоятельно.
Есть ли подводные камни для одного из этих подходов, которые я пока не вижу? Может кто-нибудь указать мне в лучшем направлении? И объяснить, почему это направление лучше?
Заранее спасибо за все ваши идеи!
4 ответа
Обычно вы хотите, чтобы ваши модели работали так, как вы о них думаете.
Например, у меня не было бы класса Address, который содержит Person. У меня был бы класс Address, содержащий только базовые данные об адресе. Лично у меня был бы адрес. Это соответствует "Человеку, живущему по этому адресу" и, скорее всего, решит проблему "кто живет". Это тип установки, которую вы используете для "Автомобиль"
"Отец", "Юность", "Брат" и т. Д. - это не атрибут личности, а атрибут отношений между людьми. Один человек может быть как "Отец", так и "Брат" и "Дядя".
Лучший дизайн примерно такой (я не знаю всех ваших требований):
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;}
}
Не вдаваясь в подробности, касающиеся всего дизайна, я остановлюсь только на проблеме адресации.
Я рекомендую, чтобы ваш класс адресов был определен так, чтобы он не имел свойства навигации обратно человеку:
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; }
}
Тогда я бы связал ваш Adult
(или даже Person
) Класс по адресу вроде так:
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; }
}
При таком подходе, если родители не разведены, они могут использовать один и тот же адрес экземпляра. В случае развода в вашем заявлении должен быть указан другой адрес для одного из родителей. Если вам нужно найти людей, живущих по одному и тому же адресу, вы можете сделать следующее:
_dbContext.Persons.Where(p => p.AddressId = addressId) ...
Если у вас есть таблица состояний, то вы можете использовать ее во многих местах: DriversLicenseState, AddressState, InsuranceState и т. Д. Если это не пустая строка, вам не нужно проверять вводимые пользователем данные, и вы можете просто удалить вниз по заявке.
Строка текущего сорта. Если вместо этого вы вводите год, в который ребенок поступил в первый класс, вам не нужно обновлять это вручную каждый год; это может быть вычислено - хотя вы также должны включить int для NumberOfYearsHeldBack. Но меньше времени обновлять этот int время от времени, чем обновлять каждого студента каждый год.
Личные предпочтения: мне нравятся "NameLast" и "NameFirst", а не "FirstName" и "LastName" только потому, что это означает, что эти свойства будут объединяться в алфавитном порядке во всех раскрывающихся списках IDE и т. Д., Так же как AddressID, Address1 и Address2
Вы могли бы подумать о превращении "Матери" в обнуляемую "Мать"? и то же самое с "Отцом" для "Отца?". У некоторых детей просто нет обоих родителей. Если вы хотите быть политкорректным, вы можете подумать "Parent1?" и 'Parent2' и укажите перечисление для выбора матери, отца, опекуна, потому что у некоторых детей есть 2 мамы или 2 папы, или их старший брат является их законным опекуном.
В вашем классе адресов есть свойство person, если у вас уже есть свойство PersonID? В этом отношении, почему у адреса есть personID вообще? Это должно быть только в одну сторону. У человека есть адрес, но у адреса нет человека. Таким образом, вы можете иметь 5 человек с одинаковым адресом. Если вы попытаетесь сохранить обе синхронизации в двух направлениях, они будут испорчены, не говоря уже о том, что у вас должен быть List<> personID внутри адреса. Поскольку адрес является типом, добавьте еще один для каждого человека, чтобы у вас были AddressPhysical и AddressMailing. Теперь у вас может быть по 4 ребенка в разных местах, где они спят, но все они получают почту на бабушкином почтовом ящике.
Я бы не стал добавлять третьего взрослого к ребенку в качестве ЛЬДА. Вместо этого я бы составил список<> взрослых (это будет просто список идентификационных номеров). Таким образом, вы можете продолжать работу над списком в чрезвычайной ситуации, пока не достигнете кого-либо.