Complex type fields - c#

I want to separate contact information in my User table, and I am thinking of two ways of doing it.
First is to make a new table and then my User table references that table through foreign key.
Or to make complex type which is part of the User table, by adding [ComplexType] annotation to Address field.
This is Address class, just an example:
public class Address
{
public string City {get; set;}
public string Street { get; set; }
public string Country { get; set; }
public string Phone { get; set; }
}
What do you recommend me to do? Which is better way?

If you ask this quesition for a clean coder then just he will answer you with two entities/classes SRP
http://www.oodesign.com/single-responsibility-principle.html
If you ask the same quesition for a database delevoper then his answer will be no joins use complex types.
Me as a developer I find Complex Types has some limitation and I will never use them.
Here I will copy from http://weblogs.asp.net/manavi/associations-in-ef-4-1-code-first-part-2-complex-types the pros and cons of the complex types:
There are three important limitations to classes mapped as Complex Types:
Shared References is Not Possible:
The Address Complex Type doesn’t have its own database identity (primary key) and so can’t be referred to by any object other than the containing instance of User (e.g. a Shipping class that also needs to reference the same User Address, cannot do so).
No Elegant Way to Represent a Null Reference:
As we saw there is no elegant way to represent a null reference to an Address. When reading from database, EF Code First always initialize Address object even if values in all mapped columns of the complex type are null.
Lazy Loading of Complex Types is Not Possible:
Note that EF always initializes the property values of a complex type right away, when the entity instance that holds the complex object is loaded. EF does not support lazy loading for complex types (same limitation also exists if you want to have lazy loading for scalar properties of an entity). This is inconvenient when we have to deal with potentially large values (for example, a property of type byte[] on the Address complex type which has been mapped to a VARBINARY column on Users table and holds an image of the location described by the Address.).
Best Practices you can read it in the given link above.

Well there's no perfect choice for this, it depends on the multiplicity: if a user have multiple addresses then you need to go with the foreign key option, if a user has only one address the you can either add the address fields to the user fields (simple) or use [ComplexType]

Your First (Separate table) choice is better, because single user have multiple contact records then it is better to handle this in separate table by foreign reference.
it is also better for changes in its contact info , means permanent address , postal address , resident contact no , self contact no and so on ,you can easily updated this in separate table ,
and this is the good practice of normalization in database

Related

Extract one specific entry from a table?

I am currently looking for a way I can pass a foreing key to a table entry that is listed in one table,
and should be extracted in another table.
for example purposes I created this ?
public class Parent
{
public string Name {get; set;}
public virtual ICollection<child> Children
Public virtual ICollection<School> Schools {get; set;}
}
public class Child
{
public string Name {get; set;}
Public School Schoola{get; set;} // Which should be a school Name that the Parent Should know?
}
public class School
{
//ParentID
//ChildID
public string SchoolName {get; set;}
}
How do i give my Child instance a SchoolName that the Parent contains within the SchoolNames?
Children and SchoolNames are seperate tables - but child only need to know a specific entry..
Caveat
Your code does not work, since EF does not serialize collections of primitive types. EF Core does have value conversions but it is unclear what you're exactly looking for. I'm going to assume you meant to store these as actual School entities, since your question asks how to "extract one entry from a table".
For the sake of answering your question, I assume that your child should have a reference to the school entity, not a string property that's technically unrelated to the school entity itself, which would make it a question not related to Entity Framework and thus the question tags would be wrong.
I'll address both my assumption and your literal question, just to be sure.
If you need a relationship between a child and a school
From a purely database standpoint, there is no way to specify that an entity's (Child) foreign key should refer to an entity (School) which in and of itself has a foreign key to another entity (Parent). It simply doesn't exist in SQL and therefore EF cannot generate this behavior for you.
What you can do, is implement business validation on your code and refuse to store any child with a school that doesn't belong to its parent. Keep in mind, this requires you to load the parent and their schools every time you want to save a child to the database (because otherwise you can't check if the selected school is allowed for this child), so it will become a somewhat expensive operation.
However, that doesn't prevent the possibility for someone to introduce data into the database (circumventing your business logic, e.g. by a DBA) where this rule is violated but the FK constraint itself is upheld.
How you handle these bad data states is up to you. Do you remove those entries when you stumble upon them? Do you proactively scan the database once in a while? Do you allow it to exist but restrict your application's users to only choosing schools from the parent's scope? These are all business decisions that we cannot make for you.
If a child needs a school name without a relation to the school itself
At first sight, this seems to me to be a bad solution. What happens when the school's name changes? Wouldn't you expect the child's schoolname to also change? Because that's not going to happen in your current setup.
In either case, if you are looking to set a string property, that's trivial, you simply set the property. Presumably, your question is how to restrict the user's options to the child's parent's schools.
This restrictive list can be fetched from the database using the child's identifier:
var childID = 123;
var schoolsFromParent = db
.Children
.Where(c => c.Id == childId)
.Select(c => c.Parent.Schools)
.FirstOrDefault();
Note that this code works regardless of whether you have a School entity or a list of strings - though the type of schoolsFromParent will be different.
And then restrict your end user to only being able to pick from the presented options. Note that to prevent bad data, you should doublecheck the chosen name after the user has selected it.

What is a complex type in entity framework and when to use it?

I have tried to read the msdn article on complex types. But it does not explain when to use it. Also there is not a comprehensive explanation on the web on complex types and when to use them.
The lengthy explanation is in the MSDN article you linked... so you basically want an easy explanation:
A complex type is a set of properties that exist in its own object for C#, but are mapped to columns on an already existing table (the one for the entity that contains it), instead of having its own table (which would need a key, etc.).
So imagine you want this table on the database:
Orders
----------
Id (bigint)
Name (varchar)
Street (varchar)
Region (varchar)
Country (varchar)
But want this structure in the C# entities:
class Order
{
long Id;
string Name;
struct Address
{
string Street;
string Region;
string Country;
}
}
So there Address would be a complex type: it would not exist on its own (there wouldn't be Addresses table) on the database... it would only exist as a set of columns on the Orders table.
As noted by #HenkHolterman in the comments, the value of having complex types is having a single C# entity which can be used as a value for other containing entities (in my example, you could have an Address in a Supplier entity, for example, but it will just be mapped as a set of columns in the Suppliers table). It makes it easy to work with the values in the complex type.
The disadvantage is precisely that one: you may have to repeat the complex type values many times in the database if it happens that a same Address (or whatever other type you use) can be shared among different entities.
Whether you choose to work with complex types or separate entities is up to you and your design.
Consider this ContactDetails class for example:
public class ContactDetails
{
public string HomePhone { get; set; }
public string MobilePhone { get; set; }
public string FaxNumber { get; set; }
}
By default, EF will treat ContactDetails as an Entity. That means that if (for example) you're having a Person class with a navigation-property of ContactDetails type, EF will map the Person.ContactDetails relationship to a different table (because Entity is something that is having an identity of its own, hence other entities may refer to it - and that would require a different table in relational terms).
By denoting ContactDetails as a Complex Type instead, EF will no longer treat it as an entity that requires a relationship and instead map it to the same table of the parent (containing) entity (Person in my example), effectively making it a Value Object.

What are Complex Types in Context with Entity Framework

Right now I am learning a lot about the Entity Framework from Videos on Pluralsight, so excuse my Question which might look newbish but I can not understand what Complex Types are or why I would need them.
I do know that I have to map them via Annotations or Fluent Api something like this:
modelBuilder.ComplexType<blubb>();
Maybe someone could elaborate the need of Complex Types for me?
Assume you have an entity for Courses in a class, that entity has scalar properties of Location, Days and Time, but you find you want to abstract that so that other entities can use the same model. So you can create a complex type that contains Days, Location and Time give it a name: ComplexType1. Now other entities can use this type rather than individual scalar properties just by declaring ComplexType1 in the model definition.
Complex Types are repeating structural patterns in your database. You have to custom map them because there is no way for it to be inferred.
An example would be two tables that both have address related columns:
Company
CompanyName
AddressLine1
AddressLine2
Postcode
Account Manager
Name
TelephoneNumber
SuperiorName
AddressLine1
AddressLine2
Postcode
This is obviously not well-normalized database design but such situations do occur. You can abstract the model for address into a complex type, then specify that both Company and AccountManager have that complex type rather than keep mapping the matching (albeit separate in the database) columns for each table that has address columns.
Here's an in depth article on Complex Types: http://msdn.microsoft.com/en-gb/data/jj680147.aspx
And here is one that isn't quite so heavy, and shows the benefit of mapping two addresses on one model, things like that: http://visualstudiomagazine.com/articles/2014/04/01/making-complex-types-useful.aspx
Complex type are types that don't map to a table like entities instead they map to one or more fields.
The following complex type
public class Descriptor
{
public string Name {get;set;}
public string Description {get;set;}
}
And entity
public class MyEntity
{
public Descriptor { get;set;}
}
This would map to a table with Name and Description fields. It is a useful way to have a type encapsulate a common set of fields/properties you might want on several entities.

Need Help With Application Design

So, I'd love some feedback on the best way to design the classes and store the data for the following situation:
I have an interface called Tasks that looks like this:
interface ITask
{
int ID{ get; set;}
string Title {get; set;}
string Description{get; set;}
}
I would like the ability to create different types of Tasks depending on who is using the application...for example:
public class SoftwareTask: ITask
{
//ITask Implementation
string BuildVersion {get; set;}
bool IsBug {get; set;}
}
public class SalesTask: ITask
{
//ITask Implementation
int AccountID {get; set;}
int SalesPersonID {get; set;}
}
So the way I see it I can create a Tasks table in the database with columns that match the ITask interface and a column that shoves all of the properties of more specific tasks in a single column (or maybe even serialize the task object into a single column)
OR
Create a table for each task type to store the properties that are unique to that type.
I really don't like either solution right now. I need to be able to create different types of Tasks ( or any other class) that all share a common core set of properties and methods through a base interface, but have the ability to store their unique properties in a fashion that is easy to search and filter against without having to create a bunch of database tables for each type.
I've starting looking into Plug-In architecture and the strategy pattern, but I don't see where either would address my problem with storing and accessing the data.
Any help or push in the right direction is greatly appreciated!!!
Your second approach (one table per type) is the canonical way to solve this problem - while it requires a bit more effort to implement it fits better with the relational model of most databases and preserves a consistent and cohesive representation of the data. The approach of using one table per concrete type works well, and is compatible with most ORM libraries (like EntityFramework and NHibernate).
There are, however, a couple of alternative approaches sometimes used when the number of subtypes is very large, or subtypes are created on the fly.
Alternative #1: The Key-Value extension table. This is a table with one row per additional field of data you wish to store, a foreign key back to the core table (Task), and a column that specifies what kind of field this is. It's structure is typically something like:
TaskExt Table
=================
TaskID : Number (foreign key back to Task)
FieldType : Number or String (this would be AccountID, SalesPersonID, etc)
FieldValue : String (this would be the value of the associated field)
Alternative #2: The Type-Mapped Extension Table. In this alternative, you create a table with a bunch of nullable columns of different data types (numbers, strings, date/time, etc) with names like DATA01, DATA02, DATA03 ... and so on. For each kind of Task, you select a subset of the columns and map them to particular fields. So, DATA01 may end up being the BuildVersion for a SoftwareTask and an AccountName for a SalesTask. In this approach, you must manage some metadata somewhere that control which column you map specific fields to. A type-mapped table will often look something like:
TaskExt Table
=================
TaskID : Number (foreign key back to task)
Data01 : String
Data02 : String
Data03 : String
Data04 : String
Data05 : Number
Data06 : Number
Data07 : Number
Data08 : Number
Data09 : Date
Data10 : Date
Data11 : Date
Data12 : Date
// etc...
The main benefit of option #1 is that you can dynamically add as many different fields as you need, and you can even support a level of backward compatibility. A significant downside, however, is that even simple queries can become challenging because fields of the objects are pivoted into rows in the table. Unpivoting turns out to be an operation that is both complicated and often poorly performing.
The benefits of option #2 is that it's easy to implement, and preserves a 1-to-1 correspondence betweens rows, making queries easy. Unfortunately, there are some downsides to this as well. The first is that the column names are completely uninformative, and you have to refer to some metadata dictionary to understand which columns maps to which field for which type of task. The second downside is that most databases limit the number of columns on a table to a relatively small number (usually 50 - 300 columns). As a result, you can only have so many numeric, string, datetime, etc columns available to use. So if you type ends up having more DateTime fields than the table supports you have to either use string fields to store dates, or create multiple extension tables.
Be forewarned, most ORM libraries do not provide built-in support for either of these modeling patterns.
You should probably take a lead from how ORMs deal with this, like TPH/TPC/TPT
Given that ITask is an interface you should probably go for TPC (Table per Concrete Type). When you make it a baseclass, TPT and TPH are also options.

DDD: Can a Value Object have lists inside them?

I'm not well versed in domain driven design and I've recently started created a domain model for a project. I still haven't decided on an ORM (though I will likely go with NHibernate) and I am currently trying to ensure that my Value Objects should be just that.
I have a few VOs that have almost no behavior other than to encapsulate "like" terms, for instance:
public class Referral {
public Case Case { get; set; } // this is the a reference to the aggregate root
public ReferralType ReferralType { get; set; } // this is an enum
public string ReferralTypeOther { get; set; }
} // etc, etc.
This particular class has a reference to "Case" which is two levels up, so if say I were going to access a Referral I could go: case.social.referral (Case, Social and Referral are all classes, there is a single Social inside a Case and there is a single Referral inside a Social). Now that I am looking at it as I type it, I don't think I need a Case in the Referral since it will be accessible through the Social entity, correct?
Now, there is no doubt in my mind this is something that should be a VO, and the method I plan to use to persist this to the database is to either have NHibernate assign it a surrogate identifier (which I am still not too clear on, if anyone could please elaborate on that too it would help me out, since I don't know if the surrogate identifier requires that I have an Id in my VO already or if it can operate without one) and/or a protected Id property that would not be exposed outside the Referral class (for the sole purpose of persisting to the DB).
Now on to my title question: Should a VO have a collection, (in my case a List) inside it? I can only think of this as a one-to-many relationship in the database but since there is no identity it didn't seem adequate to make the class an entity. Below is the code:
public class LivingSituation {
private IList<AdultAtHome> AdultsAtHome { get; set; }
public ResidingWith CurrentlyResidingWith { get; set } // this is an enum
} // etc, etc.
This class currently doesn't have an Id and the AdultsAtHome class just has intrinsic types (string, int). So I am not sure if this should be an entity or if it can remain as a VO and I just need to configure my ORM to use a 1:m relationship for this using their own tables and a private/protected Id field so that the ORM can persist to the DB.
Also, should I go with normalized tables for each of my classes, or not? I think I would only need to use a table per class when there is a possibility of having multiple instances of the class assigned to an entity or value object and/or there is the possibility of having collections 1:m relationships with some of those objects. I have no problem with using a single table for certain value objects that have intrinsic types but with nested types I think it would be advantageous to use normalized tables. Any suggestions on this as well?
Sorry for being so verbose with the multiple questions:
1) Do I need a surrogate identifier (with say NHibernate) for my value objects?
2) If #1 is yes, then does this need to be private/protected so that my value object "remains" a value object in concept?
3) Can a value object have other value objects (in say, a List) or would that constitute an entity? (I think the answer to this is no, but I'd prefer to be sure before I proceed further.)
4) Do I need a reference to the aggregate root from a value object that is a few levels down from the aggregate root? (I don't think I do, this is likely an oversight on my part when writing the model, anyone agree?)
5) Is it OK to use normalized tables for certain things (like nested types and/or types with collections as properties which would need their own tables anyway for the 1:m relationship) while having the ORM do the mapping for the simpler value objects to the same table that belongs to my entity?
Thanks again.
Take a look at the answers to related questions here and here
1) Yes - If you're storing VOs in their own table
2) If you can use a private/protected ID property, then great. Alternatively, you might use explicit interfaces to 'hide' the ID property.
But, reading into your question, are you suggesting that developers who see an ID property will automatically assume the object is an entity? If so, they need (re)training.
3) Yes it can, but with the following restrictions:
It should be quite rare
It should only reference other VOs
Also, consider this: VOs shouldn't stick around. Would it be easy/efficient to re-create the entire VO every time it's needed? If not, make it an Entity.
4) Depends on how you want to implement your Aggregate Locking. If you want to use Ayende's solution, the answer is yes. Otherwise, you would need a mechanism to traverse the object graph back to the Aggregate Root.
5) Yes. Don't forget that DDD is Persistence Ignorant (in an ideal world!).
However...
I believe Referral should be an Entity. Imagine these conversations:
Conversation 1:
Tom: "Hey Joe! Can you give me David Jone's referral?"
Joe: "Which one?"
Tom: "Sorry, I mean Referral No.123"
Conversation 2:
Tom: "Hey Joe! Can you give me David Jone's referral?"
Joe: "Which one?"
Tom: "I don't care - just give me any"
Conversation 1 suggests that Referral is an Entity, whereas conversation 2 suggests it's a VO.
One more thing: Does Referral.ReferralType change during it's lifetime (there's another hint that it should be an Entity)? If it doesn't change, consider using polyporphism and let NH handle it.
Hope that helps!

Categories