I'm using EF6 Code First, I have a sample class
public class Department
{
public Department()
{
Workers = new List<Employee>();
}
public int Id { get; set; }
public virtual List<Employee> Workers { get; set; }
}
Do I really need that horrible constructor there?
I mean, the collection will not construct itself by magic, but I write code in such a way that all EF entities are always proxies (using Create() on DbSets when I need a new object). So I first expected for those "lazy" properties just to initialize themselves. After all, that's what proxies are for, I do these kind of things with Castle.Proxy, for example. But it seems that this functionality is not included in EF, or am I wrong?
I know I can write my own monstrous-looking property for lazy initialization of this collection, and then copy it everywhere I go, but I might as well be stuck with putting it all in the constructor. My goal is for my POCOs to look Plain.
Maybe there is a way to write some custom interceptor that will first initialize the collection if it is null?
Related
I have a 'naïve' question.
With the following sample code:
public class ThisClass
{
public int ThisClassID { get; set; }
public string ThisValue { get; set;}
public ThisClass()
{
}
public ThisClass(int thisClassID)
{
using (MyContext dbContext = new MyContext())
{
this = dbContext.CaseNotes.Find(thisClassID);
}
}
}
And, of course, I get the error Cannot assign to 'this' because it is read-only
The only two ways of solving this that I know of are to have a static method, or to assign to each property separately.
Is there any way of creating a simple constructor that returns database entities into this?
UPDATE
Both answers below are correct but I can only accept one. There was some interesting discussion on the use of factories and repository patterns that were sadly deleted when a potential answer was deleted. Arguments were equally balanced both for and against with some pointing out the the Entity Framework itself is a factory that uses a repository pattern. The question itself had three upvotes and two downvotes.
The answer seems to be that there is no single answer.
You should take a look at AutoMapper, and your code could look as follows:
// Somewhere in your application/service initialization class and in some method...
Mapper.CreateMap<ThisClass, ThisClass>();
public class ThisClass
{
public int ThisClassID { get; set; }
public string ThisValue { get; set;}
public ThisClass()
{
}
public ThisClass(int thisClassID)
{
using (MyContext dbContext = new MyContext())
{
Mapper.Map(dbContext.CaseNotes.Find(thisClassID), this);
}
}
}
BTW it sounds like a bad idea. I wouldn't populate a domain object inside its own constructor.
This is a good responsibility for the repository.
Is there any way of creating a simple constructor that returns database entities into this?
In practice no. In theory you can make the type a struct. Then, the code should compile. You can assign to this in a struct.
Probably, you should not use a constructor at all. Create a factory method that simply returns the result from Find.
One unchangeable fact about constructors is that they create a fresh object every time. I don't think you want that here. You probably want to preserve the existing object instance and its identity.
I have a little utility class called ContainerQuery which consists of zero or more ContainerQueryClause objects. After the user has prepared the query (i.e. added some clauses), the interface for my framework needs to get an object that supports:
interface IContainerQuery
{
public IEnumerable<ContainerQueryClause> Clauses { get; }
}
What's the best implementation for IContainerQuery and why?
Option a)
class ContainerQuery
{
public IEnumerable<ContainerQueryClause> Clauses { get; set; }
}
Option b)
class ContainerQuery
{
public ContainerQuery()
{
Clauses = new List<ContainerQueryClause>();
}
public ICollection<ContainerQueryClause> Clauses { get; private set; }
}
Option c)
class ContainerQuery
{
public ContainerQuery(IEnumerable<ContainerQueryClause> clauses)
{
Clauses = clauses;
}
public IEnumerable<ContainerQueryClause> Clauses { get; private set; }
}
Option d)
A combination of the above approaches or a completely different approach.
Side note 1: although ContainerQuery currently looks like "it is an enumerable of clauses" I want to model it for the future's sake as "has an enumerable of clauses".
Q: Is there a general best pracitce / pattern to create properties of type IEnumerable<T>? If not, which approach fits which situations?
Side question: Would you create the interface IContainerQuery to have your internal framework use the immutable version only or would you forbear from doing so as "your internal code is not stupid enough to change the query later on"?
Some additional context: the user instantiates a new container query and wants to add some clauses. There is no funky fluent interface or things like that. After passing the finished query to my framework, my framework only wants to read all the clauses and is not allowed to make any changes to it (per interface description).
Start with the following implementation. Why? It provides minimum knowledge and possibilities to the caller.
you can use the class with the default constructor => no thinking needed
about what happens to the parameter
Clauses is always initialized => no need to check for null
Clauses is IEnumerable => minimum set of functionality, maximum flexibility for inner representation
If you can live with the implementation, you are done. If you think that a ContainerQuery without Clause doesn`t make sense, add it to the constructor so that the caller is forced to give a value. If you suggest that the caller need some methods from ICollection (adding/removing after construction of ContainerQuery) than use this interface. And so on ...
public class ContainerQuery : IContainerQuery
{
public ContainerQuery()
{
Clauses = new List<ContainerQueryClause>();
}
public IEnumerable<ContainerQueryClause> Clauses { get; private set; }
}
I have a project going on and I'd like to have one unique instance of a class.
I have a 'JobOffer' class, which has a property of type 'OfferStatus' (which is abstract and implements a state pattern). I have 'StateAvailable' and 'StateUnavailable' (or 'open' and 'closed' if you wish).
The 'JobOffer' objects have to be stored in the db.
I'd like to have just one 'StateAvailable' and one 'StateUnavailable', so when I create a new JobOffer I reference to 'StateAvailable' or 'StateUnavailable', and then I could list all the jobOffers which are Open (available) and all that are Closed (unavailable).
I know that I could do this by adding the states in the db in the seed method, and never instantiate a new state.
But I was wondering if it is possible to do a singleton or something to avoid that somebody (I mean controller, model or anything) can create new instances of that class.
public class JobOffer {
public int JobOfferId {get;set;}
public OfferState State {get;set;
public virtual ICollection<Person> People {get;set;}
//And some methods here, which depends on the state
//ie, this.State.myMethod();
My first thought was to use a boolean. Then you said you have to be able to expand to have more states, so I thought of an enum. Then you said you have this requirement to use a class, so... here's a little something I use when I want an enum with more smarts. You could call it a sort of "enumerating class", I suppose. So, your OfferState class looks like this:
public sealed class OfferState
{
public bool CanChangeState { get; set; }
//whatever properties you need
public static OfferState Available = new OfferState(true);
public static OfferState Unavailable = new OfferState(true);
public static OfferState Closed = new OfferState(false);
//whatever states you need
public OfferState(bool canChange)
{
CanChangeState = canChange;
}
}
This acts kind of like an enum, but it has properties like a class. So in your logic, you can check state:
if (jobOffer.State == OfferState.Available)
{
//stuff
}
You can also get properties off it, so you can use it to get information about the state:
jobOffer.ExpiryDate = jobOffer.CreationDate.Add(OfferState.Available.MaxDuration);
And of course, the static nature of the various states will ensure that there's only ever one instance of each.
I have a library (no source), to an certain object of which, I need to add some properties.
What would be the a way to do it ? I'm aware I could extend the class and add properties to the child. As well I know there are NO Extension Properties in C# yet. What would you suggest ? Thank you !
The metadata of class could be something like :
public class ResultClass
{
public IList<Item> Results { get; set; }
public int TotalResults { get; set; }
}
and I want to add a :
String description;
to it. Thanks.
There are a couple strategies you could take. Inheritance is the most obvious one. You might also consider composition. Can you give us some more details about what the object is and what properties you need to add to it and why?
After seeing the expanded question:
Either strategy outlined above (composition or inheritance) will probably work for you. Personally, I prefer composition. I think it better insulates you from changes that might be made to the third party library. It also forces you to work through the public interface of the library class, which is preferable when you have no knowledge or control of the internals of a class.
Here is the most basic example of composition.
public CompositeClass
{
private ResultClass _resultClass = new ResultClass();
public IList<Item> Results
{
get { return _resultClass.Results; }
set { _resultClass.Results = value; }
}
public int TotalResults
{
get { return _resultClass.TotalResults; }
set { _resultClass.TotalResults = value; }
}
//
// New Property
//
public string Description { get; set; }
}
Why do you need to add properties? If this is for binding purposes then I would suggest creating a wrapper class or creating your own inherited type that can raise PropertyChanged events in response to various state changes in your third party types. Instead of telling us your proposed solution you should tell us the actual problem you are trying to solve. Also (as I can't vote to close/migrate), this is not really a valid discussion for this site.
I think you are mixing up Extension Methods with Extension Properties.
And the last ones do not exist in C#.
So you should extend the class or create an inheriting class.
I would like to "extend" my domain classes without having to add data to the domain classes themselves. Consider I have the following class:
public class Person
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
}
And I have the following table in the database:
tblPersons
---------------
Id integer
Name varchar(50)
CreatedBy varchar(50)
CreatedDate datetime
So I don't want to add "CreatedBy" and "CreatedDate" to my domain class, because this has nothing to do with the actual domain itself...
Would it be possible to get this data whenever I load an entity? I would like to use it like this:
Person person = session.Load<Person>(1);
person.CreatedBy(); <-- CreatedBy is an Extension function
person.CreatedDate(); <-- CreatedDate is an Extension function
Can anyone point me in which direction to go in order to implement this?
I have thought about the following possibilities:
Implement a custom ProxyFactory, where I inject a custom "interface" such as IUpdateable, howver it seems like NHibernate doesn't create the proxies consistently, sometimes it loads a my "proxy class" class, and sometimes it loads the "normal class":
Person person = session.Load<Person>(2); //this will load my Proxy class of Person just fine
Address address = person.Address; //Somehow this doesn't load a Proxy for Address, but instead loads it normally - seems like it's evaluating "ImmediateLoad", which doesn't load proxies, due to lazy loading... not sure how to make this behave as I want.
Using a custom PropertyAccessor. I have read something about this - but it seems I must actually map this to a property that EXITS on the domain class... so that wouldn't work, right?
Just as NHibernate "injects" code to the runtime when creating the Proxy classes - perhaps I could do the same but inject the "interface" to the original Person class instead?
You can easily do this using a base class or a component mapping. I would not use extension methods for this purpose. I use a base class:
public abstract class Auditable : IAuditable
{
public virtual string CreatedBy { get; set; }
public virtual DateTime CreatedDate { get; set; }
}
public class Person : Auditable {}
Fluent mapping:
public class AuditableClassMap<T> : ClassMap<T> where T: IAuditable
{
public AuditableClassMap()
{
Map(x => x.CreatedBy);
Map(x => x.CreatedDate);
}
}
public class PersonMap : AuditableClassMap<Person> {}
If you are adamant about keeping audit properties out of your classes you could map the audit properties as a component.
Here is one idea. I've never implemented this, so take it with a grain of salt until you've tested it.
Create a different class that encapsulates the audit data for Person -- PersonCreation or something.
Give it an identifier, a created date, and created-by property, and a property for the Person id (I see no need actually reference the Person, unless the identifier is non-public, in which case you may want a WeakReference so you don't keep every Person instance in memory for the life of the application).
You'll need to create a mapping for NHibernate to get PersonCreation objects from the Person table.
From here, you could simply have the extension methods fetch data when called. This may or may not be reasonable depending on your usage. You'll have to create a new session every time or synchronize a static session.
Or…
In the static class that contains your CreatedBy() and CreatedDate() extension methods, create a static IDictionary<int, PersonCreation> to hold the details for each Person. Since creation data is presumably immutable, we don't really have to worry about this becoming stale.
You'll want to batch queries for the PersonCreation with your Person queries. For example, you could do something like:
var creation = session.CreateCriteria<PersonCreation>()
.Add(Restrictions.Eq("PersonId", 1))
.Future<PersonCreation>();
var person = session.CreateCriteria<Person>()
.Add(Restrictions.IdEq(1))
.UniqueResult<Person>();
By calling Future<T>(), you're telling NHibernate not to execute that query until the session is already going to database anyway.
Once you get results, you can take the first creation result and add it to the dictionary (so the extension methods have access to it), and return the person.
When you call person.CreatedDate(), the method can just pull the data from the dictionary using the id of the passed Person paramater, or the Person itself.