Entity Framework (version 6) generates classes based on your tables that look like this (where each property represents a field in the table):
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Table("dbo.MyTable")]
public partial class MyTable {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int MyTableID { get; set; }
[Required]
[StringLength(128)]
public string SomeColumn { get; set; }
public DateTime CreatedDate { get; set; }
}
I decided to provide a little more functionality, specifically a way to return an array containing the primary key of any given table. A primary key can be made up of multiple fields, and each field can be a different type. I came up with the following, using reflection and LINQ:
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
public abstract class Entity
{
public object[] PrimaryKey
{
get
{
return (from property in this.GetType().GetProperties()
where Attribute.IsDefined(property, typeof(KeyAttribute))
orderby ((ColumnAttribute)property.GetCustomAttributes(false).Single(
attr => attr is ColumnAttribute)).Order ascending
select property.GetValue(this)).ToArray();
}
}
}
I then modify each of my Entity Framework table classes to inherit Entity (ie public partial class MyTable : Entity { ... }
), so they get the PrimaryKey functionality.
A return type of object[]
made the most sense - EntityFramework's DbSet
has functions such as Find(params object[] args)
, where the return value of my PrimaryKey
property slots neatly in.
First time using LINQ, and I'm not hugely experienced with reflection, attributes or the Entity Framework. Are there any problems/gotchas with this, or any improvements?
orderby
to the query to ensure the column order (this means that every[Key]
field also requires a[Column(Order = n)]
attribute, but Entity Framework does this anyway. Of course, this solution requires EF's attributes on the fields - without them I believe it would be impossible to determine the primary key in any case. \$\endgroup\$