EntityFramework, should I use Inheritance? - c#

I have the following model, without using inheritance:
Question class:
public int QuestionId { get; set; }
public string QuestionTitle { get; set; }
public bool Required { get; set; }
public int questionType { get; set; }
[ScriptIgnore]
public virtual ICollection<TextAnswer> TextAnswers { get; set; }
[ScriptIgnore]
public virtual ICollection<ParagraphAnswer> ParagraphAnswers { get; set; }
[ScriptIgnore]
public virtual ICollection<Choice> Choices { get; set; }
[ScriptIgnore]
public virtual ICollection<ChoiceAnswer> ChoiceAnswers { get; set; }
Should I use inheritance for the answers?
That is,
TextAnswer : Answer
ParagraphAnswer : Answer
ChoiceAnswer : Answer
so that the Question class have only one ICollection ?
What would you suggest me?

Yes, the proper way to model this is with inheritance.
Note that you have some choices of how inheritance is mapped to tables (TPH, TPT) and with complex, multilevel hierarchies you may want to keep an eye on performance.

Yes. That's the advantage of Inheritance in JAVA. Through this approach you'll achieve good design for your code.
Your code will be open for new enhancements and extensions with less code changes, since base class alone will be extended for any new ANSWER class and there won't be no changes needed in question class.

My experience with inheritance and entity framework is rather poor. In specific cases (I don't want to go too much into details here) queries produced by EF had like 1Mb in size.. (I'm not talking about the results - just query text!)
Recently (about 6 months) I've started using NHibernate. In my company we have a software that is developed as a product - which means at least 3-4 levels of inheritance for each entity. NHibernate copes really well with it - you might want to give it a try.
As to EF: no don't use inheritance. This project is not mature enough.
//edit because of downvotes:
I've been using Entity Framework from the first release including hardcore things like writing custom "Custom Tool" for Visual Studio to generate code from EDMX files. The custom generator added support for stored procedures and proper lazy loading (which was broken in EF 1.0) and some more.
Then came EF 2.0 and huge changes. I've used EF in several projects. In one of them we had a requirement that all entities have one base class. This was hardcore hacking once again and this was when the case with huge query text occured. If you want to downvote my answer once again feel free to do it, but just because your case wasn't that complicated (if we can call having a base class a complicated case anyway..) doesn't mean that EF is a mature and stable ORM.

Related

How best to store a list of objects belonging to a user in ASP.NET MVC?

I'm writing an ASP.NET MVC web application that tracks characters from a game. We're using a code-first approach to make the database. One of the use cases is that the items belonging to each character be stored so they can be displayed in an inventory view.
I'm fairly new to ASP.NET MVC and I'm wondering what the best way is to store item objects that belong to the user? At the moment I have a lists of each type of item (see below). Will this approach work with Entity Framework?
public class Character : ParentClass
{
public List<Skill> Skills { get; set; }
public List<Armour> Armours { get; set; }
public List<Weapon> Weapons { get; set; }
public List<MagicItem> MagicItems { get; set; }
public List<AdventuringGear> AdventuringGears { get; set; }
}
Will Entity Framework automatically keep track of the foreign keys that link, say, a sword to the character?
Thanks in advance.
Yes! this approach will work however, it depends on quiet a few things. I am assuming other pre-requisites are met.
For Example your correct EF version and .NET version.
At the moment I have a lists of each type of item (see below). Will this approach work with Entity Framework?
Yes. Although the preferred idiom for EF is
public virtual ICollection<Skill> Skills { get; } = new HashSet<Skill>();
virtual to enable Lazy Loading, and a HashSet as there's no inherent ordering in the database, and initialized to an empty collection for convenience.
Will Entity Framework automatically keep track of the foreign keys that link, say, a sword to the character?
Yes. If you don't model Skill with a CharacterId foreign key property, EF will create one in the database behind the scenes.

Xamarin SQLite using LINQ

I got a sqlite table in xamarain (native android / pcl):
[Table("Customer")]
public class Customer
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public Address Address{ get; set; }
}
"Address" represents a second table.
1) Is it possible to automatically create the "Address" Table when I call
connection.CreateTable<CustomerDto>();
because it is it's dependency?
2) Is it possible to use a LINQ expression which automatically maps the correct "Address" to this "Customer?
In my .NET Standard library I'm using:
"sqlite-net": "1.0.8"
"sqlite-net-pcl": "1.3.1"
My approach was to create "initial state models" of all the tables, marked as abstract (so there is no risk that somebody could instantiate them), defining only the fields necessary in the database and the primary keys (GUID in my case), used only to create tables at the beginning. Following modification to the data structures always with ALTER instructions.
In another namespace a duplication of all the models, this time with getters/setters and other utilities, and I used these as "real models".
For representing linked models I used a field as Id and another one as model (refreshed when necessary):
public int IdAddress { get; set; }
[Ignore]
public Address Address { get; set; }
I don't think sqlite-net can do what you are asking because it's a very lightweight orm, and even if it could I prefer don't automate too much because of my past experiences with Hibernate.
https://github.com/praeclarum/sqlite-net
https://components.xamarin.com/view/sqlite-net
It sounds like you should look at using Entity Framework because that will allow you to use LINQ with SQLite. The standard library on the web (not Entity framework) is very light and doesn't have much functionality for the ORM like functionality you are looking for.
If you're looking for a more lightweight library, you can use this, but it will not allow you to write LINQ expressions without writing your own ORM:
https://github.com/MelbourneDeveloper/SQLite.Net.Standard

How can I set EntityState.Modified automatically for objects referenced through a navigation property when the parent object is modified?

In my .NET MVC Web API project with EntityFramework I have these models; Store and Course. I override SaveChanges() in DbContext to increment a version property on each update.
What I would like to do is that when I update a course object, by changing the location property for example, I would like to increment the version property of each of the store objects that are referenced from the course object.
Is there any way to automatically set the state of the referenced objects to EntityState.Modified so the version property on these objects gets incremented as well or do I have to do it manually?
Any suggestion is highly appreciated if there's any other way I should be doing this.
Store:
public class Store : BaseModel {
public string name { get; set; }
...
public int version { get; set; }
}
Course:
public class Course : BaseModel {
public string location { get; set; }
public int version { get; set; }
...
public virtual List<Store> stores { get; set; }
}
DbContext SaveChanges() Override:
case EntityState.Modified:
dbEntityEntry.Entity.version += 1;
break;
You could use Object.GetType in your overriden SaveChanges method to detect such a case and implement your logic from there.
If I understand correctly though, I'm not entirely sure this is the right way to do things; this seems like pretty specific domain logic at first and should thus probably appear in a higher-level layer, not your DAL.
If your usage of version properties is systematic across all kinds of entities (not specific), then you might want to make a small abstraction layer on top of EF to handle your versioning needs. I'm not aware of any such project around EF. For this you would probably need to dive into the Metadata Workspace to retrieve all navigation properties for a given entity.
But then again, I'm not sure how one would determine whether an associated entity's version should be bumped or not. After that there's the depth/propagation problem, if the versions of the associated entities are bumped, should the versions of their own associated entities be bumped as well? At first sight, it seems that this can't be generalized and is inherently domain specific. I might be wrong.

POCO classes and ViewModels in MVC3

I am not an experienced MVC3 developer but I'm trying to be. I am familiar with POCO classes and also ViewModels, as the former describes each classes of the database and the latter is used for strong type views in mvc3. My question is not that complicated for the experienced developers but I am a little confused about that.
The matter is that, I have a solution containing three projects;
The Model class library in which I have wrote my POCO classes. Here is an example:
.
public class Service
{
[Key]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int ServiceID { get; set; }
//------------------------------------------------------------//
[Required, MaxLength(30)]
[LocalizedAttribute("Name")]
public string Name { get; set; }
//------------------------------------------------------------//
[MaxLength(100)]
[LocalizedAttribute("Description")]
public string Description { get; set; }
//------------------------------------------------------------//
[Required]
public long ModifiedByUserID { get; set; }
[ForeignKey("ModifiedByUserID")]
public virtual User OperatorUser { get; set; }
//------------------------------------------------------------//
[Required, MaxLength(10)]
public int ModifiedDate { get; set; }
}
The repository and UnitOf Work class Library
The MVC application
Now, Did I correctly address the POCO classes? (I am using EF Code First to generate the database of course) If So, are they inferred as ViewModels too? I have used them to generate Strongly-Type View.
What is the best and actually standard way to define POCO classes and ViewModels?
I would appreciate any kind guidance,
To be honest, it depends on the size of your project.
If you look at most of the Microsoft examples, they use their POCOs as Models simply because their examples are small projects.
If however you are developing anything near an enterprise level application you really shouldn't be using your POCO's as models. There should be clear separation of concerns. Strictly speaking your Web project shouldn't even know about your POCO objects in those scenarios, a typical implementation is a common interface that both the POCO and the View Model can implement and see. That way saves you exposing your POCO objects to your Web layer.
ViewModel is a middle layer between data(Poco) and View, which usually contains additional logic to control UI.
If ViewModel doesn't have any specific data, I don't see the reasons not to use Poco as ViewModel.
In other case, to keep data as Poco, you can create ViewModel with the same fields as your Poco class and use Automapper to Poco->ViewModel, ViewModel->Poco transformation.
I agree with mt_serg. In my application, I use POCO classes directly if it is a straightforward case.
However if in my view I also need to display for example drop-down lists that are populated from the db, then I create a ViewModel that includes the POCO classes with the additional lists and use the VM in the view passed in from the controller. I don't however redo my work and create the VM with the same fields as the POCO + additional fields. I find this method works for me, since I do not have to take care of transformations myself and I let the MVC framework sort that out for me. Hope this helps

Entity framework entity class mapping with a plain .NET class

I have the following in Entity Framework.
Table - Country
Fields
List item
Country_ID
Dialing_Code
ISO_Alpha2
ISO_Alpha3
ISO_Full
I would like to map only selected fields from this entity model to my domain class.
My domain model class is
public class DomainCountry
{
public int Country_ID { get; set; }
public string Dialing_Code { get; set; }
public string ISO_3166_1_Alpha_2 { get; set; }
}
The following will work, however insert or update is not possible. In order to get insert or update we need to use ObjectSet<>, but it will not support in my case.
IQueryable<DomainCountry> countries =
context.Countries.Select(
c =>
new DomainCountry
{
Country_ID = c.Country_Id,
Dialing_Code = c.Dialing_Code,
ISO_3166_1_Alpha_2 = c.ISO_3166_1_Alpha_2
});
Is there a nice solution for this? It wound be really fantastic.
Ideally it will be kind of proxy class which will support all the futures however highly customizable.
That is, only the columns we want to expose to the outer world.
The term for "plain .NET classes" is POCO - plain old CLR objects (inspired by POJO, plain old Java objects).
Read this blog post series, it helped me a lot:
http://blogs.msdn.com/b/adonet/archive/2009/05/21/poco-in-the-entity-framework-part-1-the-experience.aspx
I want to do the same thing. My goal is to build a WCF service that can use the same set of objects as the application I'm building by sharing a DLL and sending/receiving the same classes. Additionally, I also wanted to limit what fields are exposed. After thinking about this for a while it seems a user-defined cast might do the trick. Have a look to see if it works for you.
http://www.roque-patrick.com/windows/final/bbl0065.html

Categories