I am working on an application which currently creates data entity objects from the results of a sql query. In the database 3 of the tables are very similar but have several different properties.
My initial plan was to create 3 different classes, even though each class is very similar. However when I came to create the method which returns a list of objects, I have hit a stumbling block as the return type will be different depending on which mode the application is in.
e.g.
public class A
{
public int Id {get;}
public string Name {get;}
}
public class B
{
public int Id {get;}
public string Name {get;}
public string ExtraInfo {get;}
}
public class MainScreen
{
...
this.resultsGrid.DataSource = LoadData();
}
I would prefer not to write one method to load a list of each data type.
What should the return type of LoadData() be, to allow it to be generic as possible.
What is the most elegant way of dealing with this scenario?
Thanks,
Sean
You should have inheritance to allow polymorphism, so you would have a base class that all entities included in the data binding derive from it.
Then, you can have a mid-base class to have some shared properties like Name and ID.
Base class:
public abstract class Entity
{
}
Entity with Name and ID:
public class NameAndIDEntity : Entity
{
public int Id { get; set; }
public string Name { get; set; }
}
Entity with Name, ID and ExtraInfo:
public class NameIDAndExtraEntity : NameAndIDEntity
{
public string ExtraInfo { get; set; }
}
Entity with other information (can't be derived from NameAndIDEntity), derives from Entity so it can be included in the data binding:
public class OtherInformationEntity : Entity
{
public int Age { get; set; }
}
Finally, you can make the LoadData return type Entity.
Simples!
Create a class ListItem (with properties Id and Name, I presume). In your factory class/method, make instances of that class from the records into a List and bind the datasource to the list.
Don't be scared to create specialised classes for your UI.
UPDATE: Forgot to mention. Avoid inheritance as much as possible.
First you can create an inheitance tree in your project, where base class holds a shared/common properties among set of dfferent types
Second you can retrieve from the query anonymous type and after map it to a known type by mapping them to a real type, like from Jon Skeet's blog Horrible grotty hack: returning an anonymous type instance
That means that you need by the way know which query what type returns (can not avoid that), but this can reduce amount of fraction you need to add to your code, like from example:
static class GrottyHacks
{
internal static T Cast<T>(object target, T example) //CAST TO SPECIFIED TYPE
{
return (T) target;
}
}
class CheesecakeFactory
{
static object CreateCheesecake()
{
return new { Fruit="Strawberry", Topping="Chocolate" };
}
static void Main()
{
object weaklyTyped = CreateCheesecake(); //ANONYMOUS TYPE GENERATION
var stronglyTyped = GrottyHacks.Cast(weaklyTyped,
new { Fruit="", Topping="" }); //"MAPPING"
Console.WriteLine("Cheesecake: {0} ({1})",
stronglyTyped.Fruit, stronglyTyped.Topping);
}
}
Related
I have base class, and multiple derived classes, like that:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Parent : Person
{
public int Age { get; set; }
}
public class Child : Person
{
public int Grade { get; set; }
public Parent Father { get; set; }
public Parent Mother { get; set; }
}
Each class has a table in the DB, with an appropirate field.
When I want to obtain data from the DB, and initalize an Person's instance, I need to set value for each property, like that:
Name = reader["Name"].ToString();
Age = int.Parse(reader["Age"].ToString());
Now, I don't want to do that on each derived class, but do that generally in the base class.
What is the best way to do that? Thank you.
First of all, the best answer you can find here is: adopt an OR/M like Entity Framework, NHibernate or Dapper (or any other) and focus your efforts in your business instead of wasting your time in infrastructure details!
In the other hand, if you want an approach to solve your issue using your own code, I would say you need to create the concept of data mapper. It would be a class which should define mapping between relational and object-oriented counterparts.
This way, when you try to obtain a derived class, you instantiate base class and derived class data mappers, and you call them to obtain the entire column data:
DerivedClass derivedClassInstance = new DerivedClass();
DerivedClassDataMapper derivedMapper = new DerivedClassDataMapper(derivedClassInstance, dataReader);
derivedMapper.Fetch();
// Now your derivedClassInstance reference will contain an object which
// has both data from base and derived class...
Finally, I would say that both data mappers should inherit from a DataMapper base class where Fetch method should be marked as virtual (or abstract) in order to let derived data mappers add more mapping code (this way, base mapper will map properties to columns defined in the base class, derived class will override Fetch to add more mappings and so on...).
Anyway, you shouldn't reinvent the wheel because there're solid object-relational mappers.
I have a class with over 100 uniquely named properties and more than 20 child-classes, sometimes in lists. Below is a greatly simplified illustration of what I mean:
public class classA
{
public String PropertyA1 { get; set; }
public int PropertyA2{get;set;}
public List<classB> myList;
public classC myClass { get; set; }
public void SetProperty(String PropertyName)
{
// Match property name to property in this class or child class.
}
}
class classB
{
public String PropertyB1 { get; set; }
public bool PropertyB2 { get; set; }
}
class classC
{
public String PropertyC1 { get; set; }
}
I would like to do two things that may or may not be possible. The first thing I need to do is iterate through every public property, including those of child classes and classes in a list, and translate the values. I know I can accomplish the parsing by serializing to xml and parsing through the results. I even have the code in place to convert to xml, as the function of the class is to build an xml object. However, I am worried that parsing through the xml might be much more expensive than accessing the properties through reflection. Can reflection be used in this manner, and would it be quicker than modifying the xml?
The other thing I would like to do is access any property passing the property name into a method. I realize I would need a separate method for accessing classes within lists, and may have to convert the list to a dictionary. The question is, would this be possible, and would the code only need to be in the parent class, or would each of the child classes need to repeat the code?
Method that will set the property with the given name:
public void SetProperty(String propertyName, object value)
{
this.GetType().GetProperty(propertyName).SetValue(this, value);
}
A few things about the implementation:
The type used is the dynamic actual type of the object, that will find members that are in derived classes (as long as the object is of the derived type of course).
The property info has no idea of what object it came from, so this must be passed in again to the SetValue() call.
The second part of your question, to iterate through a list of properties, can be solved by using GetProperties() to get all the properties of the object, including inherited ones:
var properties = this.GetType().GetProperties();
I've stumbled upon the need to do this a few times recently with some lower level framework type stuff and I'd like to see if there is a better/cleaner way to accomplish this, i.e. if I'm missing something obvious or clever, like the time I discovered [ThreadStatic] to replace dictionary lookups against thread IDs for associating data with Threads.
I have a base abstract class, lets call it Entity. Every Entity needs to perform a set of initialization actions in the constructor that depends on the actual concrete class being instantiated. Is there a way I can accomplish this without doing a dictionary lookup and calling this.GetType()?
Here is some code similar to what I have now:
public abstract class Entity
{
private static Dictionary<Type, Action<EntityData>> _initActions = new Dictionary<Type, Action<EntityData>>();
private EntityData _data = new EntityData();
protected Entity()
{
_initActions[this.GetType()].Invoke(_data);
}
}
public class Employee : Entity
{
public string Name { get; set; }
}
public class Manager : Employee
{
public List<Employee> Subordinates { get; set; }
}
The Employee constructor and Manager constructor need to initialize their _data fields differently as they are different types. The _initActions collection gets initialized in another method prior to any instances being new'd up, which I don't think has any significance on this discussion.
I want usage of the class to remain as simple as possible for the user of the framework, so I can't use strange hacks like requiring users to override an Init method in each concrete type in some peculiar or unintuitive way.
Generics almost work, in the sense that I could do something like Entity<TEntity> to get a TEntity specific static field to store the init method if I didn't have any inheritance, but inheritance needs to be supported so I would need a dictionary of all init methods for the subclasses of TEntity anyway.
This code runs in some pretty low level database engine type scenarios in tight loops with 1m iterations, so getting rid of the dictionary lookup does provide some significant speedups in certain situations (tested by replacing with a hacky Init override implementation).
Any ideas?
EDIT:
I want to make a few things clear. The entity engine automatically sets up _initAction to do what it needs to to initialize its _data container. The "user" of the library knows nothing about this process and doesn't need to. All I was inquiring about is a way to avoid a dictionary lookup to get type-specific runtime information from a base class, but that may not be possible.
Yes, this is micro-optimization, but we have tested this with real queries and gotten 15-20% query time reductions on some queries that need to instantiate large datasets.
The faster code looked like this:
public class Employee : Entity
{
private static EntityInitializer _initMethod = Entity.GetInitMethod(typeof(Employee));
public string Name { get; set; }
public Employee()
{
_initMethod.Invoke(this);
}
}
This way, the dictionary lookup is done once for the Employee type. It's not horrible, but it requires a) boilerplate in every single class, which I don't like and b) slightly error prone as you have to match up the type parameter with the current class otherwise funky things happen, kind of like when you type in the wrong owner class name for a dependency property in WPF. Kinda sometimes works, but then wierd bugs pop up and its hard to trace back.
What it comes down to is this: is there was a better way to attach arbitrary runtime data to a Type besides using a Dictionary, considering that all these types that will have this data attached to them all implement a common base class?
Could you not just create a ctor that you pass the type to?
protected Entity(Type type)
{
_initActions[type].Invoke(_data);
}
}
public class Employee : Entity
{
private static Type mytype = typeof(Employee);
public string Name { get; set; }
public Employee(): base(mytype)
{ }
}
The lookup is causing performance issues?
Dictionary lookup is 0(1) and few milliseconds.
A program can only have so many classes.
Entity still needs to create the object, create a new EntityData, and run Invoke.
In addition to initialization of the classes that implement Entity.
Why does the type of the sub class effect the way an encapsulated class should be populated?
This seems like a violation of some OO principles to me.
If there is some specialized behaviour for a subclass, then
public abstract class Entity
{
private readonly EntityData data = InitializeData(new EntityData());
protected abstract void InitializeData(EntityData data);
}
seems like a better definition for the base class. The specilased action can be defined in the sub class,
Public class Employee : Entity
{
protected override void InitializeData(EntityData data)
{
// Employee specific implementation here ...
}
}
This requires no Dictionary, lookup or even a switch statement. No static state is required. It means the sub class related code has to be in the sub class but, that is a good thing, that is OO.
If its necessary to preserve more of what you have your could do somthing like,
public abstract class Entity
{
private readonly EntityData data;
protected Entity(Action<EntityData> initializeData)
{
this.data = initializeData(new EntityData());
}
}
public class Employee : Entity
{
public Employee : base(SomeStaticAction)
{
}
}
I really feel like you're overthinking this. Why not just have Entity have an abstract get-only property that needs to be overridden?
public abstract class Entity
{
private static Dictionary<Type, Action<EntityData>> _initActions =
new Dictionary<Type, Action<EntityData>>();
protected abstract EntityData _data { get; }
protected Entity()
{
_initActions[this.GetType()].Invoke(_data);
}
}
public class Employee : Entity
{
public string Name { get; set; }
protected overrides EntityData _data {
get { return new EntityData("Employee Stuff"); }
}
}
public class Manager : Employee
{
public List<Employee> Subordinates { get; set; }
protected overrides EntityData _data {
get { return new EntityData("Manager Stuff"); }
}
}
Alternatively, just have two Init methods.
public abstract class Entity
{
private static Dictionary<Type, Action<EntityData>> _initActions =
new Dictionary<Type, Action<EntityData>>();
private void InitalizeBase() { /* do shared construction */ }
protected abstract void Initalize();
protected Entity()
{
InitalizeBase();
Initalize();
}
}
public class Employee : Entity
{
public string Name { get; set; }
protected overrides Initalize()
{
// Do child stuff
}
}
I have some classes with common properties, however, I cannot make them derive from a base type (LINQ-to-SQL limitations).
I would like to treat them as if they had a base type, but not by using Reflection (performance is critical).
For example:
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
}
public class Vehicle
{
public int Id { get; set; }
public string Label { get; set; }
}
In this case I would be happy if I had the Id property available, regardless of the type I'm holding.
Is there any way in C# to to something similar to this:
public static int GetId<T>(T entity) where T // has an int property 'Id'
{
return entity.Id;
}
I guess I could have used dynamic, however, I'm looking for a way to restrict the code in compile time from using this method for an object that has no Id property.
You can use interfaces:
public interface IHasId
{
int Id { get; }
}
public class User : IHasId { ... }
public class Vehicle : IHasId { ... }
public static int GetId<T>(T entity) where T : IHasId
{
return entity.Id;
}
However, if you are not able to modify the classes to add the interface, you won't be able to do this. No compile-time checks will verify that a property exists on T. You'd have to use reflection - which is slow and obviously not ideal.
There is no way to guarantee a type has a given member without constraining to a common base type or interface. One way to work around this limitation is to use a lambda to access the value
public static int Use<T>(T value, Func<T, int> getIdFunc) {
int id = getIdFunc(value);
...
}
Use(new User(), u => u.Id);
Use(new Vehicle(), v => v.Id);
You can create an interface with the common properties and make your classes implement it:
public interface IEntity
{
int Id { get; set; }
}
public class User : IEntity
{
public int Id { get; set; }
public string FirstName { get; set; }
}
public class Vehicle : IEntity
{
public int Id { get; set; }
public string Label { get; set; }
}
public static int GetId<T>(T entity) where T : IEntity
{
return entity.Id;
}
You could simplify GetId like this:
public static int GetId(IEntity entity)
{
return entity.Id;
}
The other answers mentioning the interface approach are certainly good, but I want to tailor the response to your situation involving Linq-to-SQL.
But first, to address the question title as asked
Can C# constraints be used without a base type?
Generally, the answer is no. Specifically, you can use struct, class, or new() as constraints, and those are not technically base types, and they do give some guidance on how the type can be used. That doesn't quite rise to the level of what you wish to do, which is to limit a method to types that have a certain property. For that, you will need to constrain to a specific interface or base class.
For your specific use case, you mention Linq-to-SQL. If you are working from models that are generated for you, then you should have options to modify those classes without modifying the generated model class files directly.
You probably have something like
// code generated by tool
// Customer.cs
public partial class Customer // : EntityBaseClasses, interfaces, etc
{
public int ID
{
get { /* implementation */ }
set { /* implementation */ }
}
}
And other similar files for things such as Accounts or Orders or things of that nature. If you are writing code that wishes to take advantage of the commonly available ID property, you can take utilize the partial in the partial class to define a second class file to introduce a common interface type to these models.
public interface IIdentifiableEntity
{
int ID { get; }
}
And the beauty here is that using it is easy, because the implementation already exists in your generated models. You just have to declare it, and you can declare it in another file.
public partial class Customer : IIdentifiableEntity { }
public partial class Account : IIdentifiableEntity { }
// etc.
This approach has proven valuable for me when using a repository pattern, and wishing to define a general GetById method without having to repeat the same boilerplate in repository after repository. I can constrain the method/class to the interface, and get GetById for "free."
Either you need to make both classes implement an interface with the properties you need, and use that in the generic constraint, or you write separate methods for each type. That's the only way you'll get compile-time safety.
I have a class like this
public abstract class BaseType<T>
{
public string Name {};
public T TypedValue {
get {
return GetTypedValue(PersistedValue);
}
};
public string PersistedValue {}
public abstract T GetTypedValue(PersistedValue);
}
then many derived classes like
public class IntegerType:BaseType<int>
{
...
}
is it possible to map this hierarchy using EF 4.0 using Table per inheritance scheme ?
Currently the generated code creates has an error because it generates a property like
public <T> ObjectSet<TypedAttribute<T>> TypedAttributes
{
get
{
return _typedAttributes ?? (_typedAttributes = CreateObjectSet<TypedAttribute<T>>("TypedAttributes")); }
}
private ObjectSet<TypedAttribute> _typedAttributes;
I don't think so because:
Inheritance mapping requires the base class to be entity in EDMX.
When inheritance is used the ObjectSet is for base type. What generic argument would you use to create an instance of ObjectSet when it has to be used to retrieve any subtype?
It can be partially achieved without inheritance (at least for POCOs). Simply model your subtypes in EDMX without base type. Then manually create POCO classes and derive them from generic base types. The only rule you have to follow is that POCO class must have the same name as entity in EDMX and it must have all its properties with accessibility set in EDMX. If you want to use change tracking properties must be marked as virtual. If you want to use lazy loading navigation properties must be virtual as well.
Example:
Suppose that I have two entities in EDMX: IntegerValue and DoubleValue. Now I defined these POCOs as follows:
public abstract class BaseType<T>
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual T Value { get; set; }
}
public class IntegerValue : BaseType<int>
{ }
public class DoubleValue : BaseType<double>
{ }
It will result in single table per sub type.