As I embarked on a new mission to write a home media server application in C#, I needed a way to store an index of media files on my home computer. I could have gone the flat-file route, and stored file information in a simple delimited index file. Instead, I decided to delve into object-relational mapping (ORM) using the .NET Entity Framework. I’ve used ORM in past Java projects, utilizing the EclipseLink implementation of the Java Persistence API. If you’re not familiar with ORM, it basically lets you store and retrieve Objects in a standard relational database (T-SQL, MySQL, Oracle, etc.) without having to code SQL-queries (unless you want to). If you already have an existing database, ORM can generate classes based on tables in your database. If no database exists, as was the case in my media server project, ORM can take care of setting up the database tables and fields and matching classes for you. Early on in my project, some of my .NET Entity Framework auto-generated classes were not compiling. I was receiving the error: “does not contain a constructor that takes 0 arguments”. Since these classes were sub-classed from a custom abstract class, I realized I needed to somehow add an appropriate constructor to these auto-generated classes.
Any edits you make in the auto-generated classes will be overwritten if you make changes to your database model, which will cause all of these classes to be re-generated from scratch. If you need to add any logic to your classes, you’ll need to create separate partial classes. I created an abstract MediaFile class as a base class for specific media file types (Music, Videos and Images). To identify each file, I wanted to use a hash of the file-path, which I added as a member of the abstract base class. Since this ID also served as the primary key in the database table, this needed to be generated whenever a new object was instantiated. To facilitate this, I created a partial class implementation for MediaFile which defined a constructor that takes one argument: the file-path of the media file. This allowed the ID to be generated immediately upon object creation, ensuring no MediaFile object existed without a unique ID. After defining the partial class and adding this constructor logic, my project no longer compiled. Instead, I received errors similar to the following:
Error 'Devineloper.MediaServer.Model.MediaFile' does not contain a constructor that takes 0 arguments
To fix this error, I had to create partial class implementations for each of the MediaFile child classes. These partial classes simply defined a constructor that took one argument that is sent to the base (MediaFile) constructor. Note that when defining a partial class to implement an auto-generated partial class, you must choose a file name that does not conflict with the auto-generated class name. I chose the following naming scheme: ClassName.implementation.cs.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Devineloper.MediaServer.Model { public partial class MusicFile { public MusicFile(string filepath) : base(filepath) { } } } |
With these simple partial classes and constructors created, the program compiles again and I can continue on with my project and exploration of the .NET Entity Framework.