How to Extend a Fieldset in ZF2 - doctrine

Doctrine’s Class Table Inheritance mapping strategy involves joining a parent table with one of a number of child tables depending on the value in a discriminator column in the parent table. For example, a parent table might contain the columns a, b, and c; with the values in column c being either foo or bar. A child table named ‘foo’ might contain the columns d, e, f and g; while a child table named ‘bar’ might contain the columns p, q, r and s. A single entity is defined for the parent and a separate entity is defined for each child (‘foo’ and ‘bar’). In the inheritance mapping strategy, the child entities ‘extend’ the parent entity, so there is no need in the child to redefine elements in the parent.
My question is, can we ‘extend’ the child fieldsets as well? The ‘foo’ fieldset is going to consist of elements a, b, c, d, e, f and g and the ‘bar’ fieldset is going to consist of elements a, b, c, p, q, r and s. Do we really need to define the options and attributes for elements a, b, and c more than once? Doing so multiplies the amount of code, and requires diligence in ensuring that a, b, and c are defined identically in every ‘foo’ and ‘bar’.

The short answer is yes you can.
class FieldsetParent extends Zend\Form\Fieldset
{
public function init() {
$this->add(array('name' => 'fieldA'));
$this->add(array('name' => 'fieldB'));
$this->add(array('name' => 'fieldC'));
}
}
class FieldsetFoo extends FieldsetParent
{
public function init() {
parent::init();
$this->add(array('name' => 'fieldD'));
$this->add(array('name' => 'fieldE'));
$this->add(array('name' => 'fieldF'));
$this->add(array('name' => 'fieldG'));
}
}
class FieldsetBar extends FieldsetParent
{
public function init() {
parent::init();
$this->add(array('name' => 'fieldP'));
$this->add(array('name' => 'fieldQ'));
$this->add(array('name' => 'fieldR'));
$this->add(array('name' => 'fieldS'));
}
}

Related

linq with Include and many-to-many

I have rather specific requirement for my Linq statement. I've looked through dozens of examples, but could't find satisfying answer.
I have a collection of courses, which holds collection of groups, which holds collection of members. My goal is to create linq statement for IQuerable which returns a collection of courses that user belongs to, and includes collection of groups within each course that user belongs to if there is any.
I did manage to build a linq statement which returns what I wanted but filters out all of the courses that don't have any groups that user belongs to inside them:
var courses2 = (from c in _set
from s in c.Students
where (s.UserName == userName)
from g in c.Groups
from m in g.Members
where (m.UserName == userName)
select c)
.Include(c => c.Groups)
.OrderBy(c => c.Title)
How could I change it to include those as well?
Assuming your student entity has a nav property to entity Class for class membership, and Class entities have a nav property Groups to the Group entity, which in turn have a nav property to Students:
// get the students to query against
var students = db.Students.Where( s => s.UserName == userName );
// get classes per group
var classesViaGroups =
students.SelectMany( s => s.Groups )
.SelectMany( g =>
g.Classes.Select( c =>
new { GroupName = g.Name, ClassObj = g.Class } ) );
// get classes by the student entities alone
var classesViaStudents =
students.SelectMany( s => s.Classes )
.Select( c => new { GroupName = null, ClassObj = c } );
You can then do what you will with classesViaGroups and classesViaStudents - combine them, build a lookup or dictionary by group or class, etc.

Can I convert a Func<T, bool> to a Func<U, bool> where T and U are POCO classes where I can map properties of one to the other? If so, how?

I have a scenario where a method will take a predicate of type Func< T, bool > because the type T is the one that is exposed to the outer world, but when actually using that predicate I need that method to call another method that will take in Func< U, bool > where properties of T are mapped to properties of U.
A more concrete example would be:
public IEnumerable<ClientEntity> Search(Func<ClientEntity, bool> predicate)
{
IList<ClientEntity> result = new List<ClientEntity>();
// Somehow translate predicate into Func<Client, bool> which I will call realPredicate.
_dataFacade.Clients.Where(realPredicate).ToList().ForEach(c => result.Add(new ClientEntity() { Id = c.Id, Name = c.Name }));
return result.AsEnumerable();
}
Would that be possible?
Please note that ClientEntity is a POCO class that I defined myself while Client is an Entity Framework class created by the model (DB first).
Thanks!
I once attempted this. It resulted in a not-too-bad working expression tree rewriter when the expression tree consist of the simpler operations (equals, larger-then, smaller-then, etc).
It can be found here.
You can use it as:
Expression<Func<Poco1>> where1 = p => p.Name == "fred";
Expression<Func<Poco2>> where2 = ExpressionRewriter.CastParam<Poco1, Poco2>(where1);
EF doesn't use lambdas - it uses Expression Trees
Func<T, bool> lambda = ( o => o.Name == "fred" );
Expression<Func<T, bool>> expressionTree = ( o => o.Name == "fred" );
Expression Trees are in-memory object graphs that represent a given expression.
As they are just objects, you can create or modify them.
Here's another link: MSDN: How to: Modify Expression Trees
What I ended up doing did not require the use of Expression Trees:
public IEnumerable<ClientEntity> Search(Func<ClientEntity, bool> predicate)
{
IList<ClientEntity> result = new List<ClientEntity>();
Func<Client, bool> realPredicate = (c => predicate(ConvertFromClient(c)));
_dataFacade.Clients.Where(realPredicate).ToList().ForEach(c => result.Add(ConvertFromClient(c)));
return result.AsEnumerable();
}
private static ClientEntity ConvertFromClient(Client client)
{
ClientEntity result = new ClientEntity();
if (client != null)
{
// I actually used AutoMapper from http://automapper.org/ here instead of assigning every property.
result.Id = client.Id;
result.Name = client.Name;
}
return result;
}

Filter a List<T> based on another list that each instance of T contains

So I have a collection of objects in one list, but each object in that list contains another list.
Consider the following:
class Parent
{
public Parent(string parentName)
{
this.ParentName = parentName;
}
public string ParentName { get; set; }
public List<Child> Children { get; set; }
}
class Child
{
public Child(string name)
{
this.ChildName = name;
}
public string ChildName { get; set; }
}
By the nature of the application, all Parent objects in the list of parents are unique. Multiple parents can contain the same child, and I need to get the parents that contain child x.
So, say the child with ChildName of "child1" belongs to both parents with ParentName of "parent1" and "parent5". If there are 100 parents in the collection, I want to get only the ones that have the Child with ChildName of "child1"
I would prefer to do this with a lambda expression but I'm not sure where to start as I don't really have to much experience using them. Is it possible, and if so, what is the correct approach?
If the Child class has defined an equality operation by implementing IEquatable<Child>, you can do this easily by using a lambda, the Enumerable.Where method of LINQ and the List.Contains method:
var parents = new List<Parent> { ... }; // fully populated list of parents
var child = null; // the child you are looking for goes here
var filtered = parents.Where(p => p.Children.Contains(child));
You can now iterate over filtered and perform your business logic.
If the Child class does not have an equality operation explicitly defined (which means that it will use reference equality rules instead of checking for identical ChildName), then you would need to include the "what passes for equal" check into the lambda yourself:
var filtered = parents.Where(p => p.Children.Any(c => c.ChildName == "child1"));
Note: There are of course many other ways to do the above, including the possibly easier to read
parents.Where(p => p.Children.Count(c => c.ChildName == "child1") > 0);
However, this is not as efficient as the Any version even though it will produce the same results.
In both cases, the lambdas very much "read like" what they are intended to do:
I want those parents where the Children collection contains this item
I want those parents where at least one of the Children has ChildName == "child1"
You can do it like this:
var result = parents.Where(p => p.Children.Any(c => c.ChildName == "child1"));
This would do it
IEnumerable<Parent> parentsWithChild1 = parents.Where(p => p.Children.Any(c => c.ChildName == "child1"));

LINQ/Projection - How to sort TableA by non FK column id/name field per TableB?

How can I use LINQ/Projection to sort a list of A objects that contain an id field that references table/object B (B contains id and name).
I want to sort list of A objects that contain B by B.name?
Model (pseudo)
public class A
{
public int AId {get; set;}
public Nullable<int> BId {get; set;}
}
public class B
{
public int BId {get;set;}
public string Name {get;set;}
}
Code in some controller passing in a list of A's that contain B's but sort them by B.Name?
var list = db.As.OrderBy(x => x.BId->References.Name); // Way wrong but using something similar
return(list.ToList()
Basically, looking for the equivalent of this (using projection join or OrderBy from above):
var q1 =
from a in db.As
join b in db.Bs on a.BId equals b.BId
orderby b.Name // <- Need this to sort by B's name
select c;
Am I right that you are looking for the equivalent to the LINQ query you have already written above, only that it is based on extension methods instead?
In this case the following should work:
var list = db.As.Where(a => a.BId.HasValue)
.Join(db.Bs, a => a.BId.Value, b => b.BId, (a, b) => new { a, b.Name })
.OrderBy(r => r.Name)
.Select(r => r.a);
I've also added a check to make sure A.BId is not null before getting its value.
Just curious: why can't you use your LINQ query (with the only difference of selecting a instead of c)?

Linq to NHibernate - select count problem

Given the classes A and B where
class A
{
string Name;
Ilist<B> BList;
}
class B
{
string Name;
}
With FluentNH mapping, relationship is many-to-many which is HasManyToMany(x => x.B) for A. B has no reference to A. NH version is 2.1.2.4000.
What should be the linq query to select the collection where each row contains B.Name and count of A's containing that B? Result must be the List of anonymous type who has 2 fields: Name and Count. Result also should include all B's, hence it should be outer join.
My intend is to get the result with minimum round-trips to database, possibly in one go.
If you want to do it in Linq in one hit in code, you could do this...
var result = Session.Linq<A>()
.SelectMany(a => a.BList, (a, b) => new { b.Name, A = a.Id })
.ToList()
.GroupBy(x => x.Name)
.Select(x => new { Name = x.Key, Count = x.Count() })
.ToList();
NHibernate.Linq (2.1.2.4000) can't handle a GroupBy after a SelectMany it seems, so the first ToList pulls all the data into memory. This is inefficient -- a SQL count would be better.
Alternatively, you could add a lazy loaded collection to your B class that goes back to A. If you're using a many-to-many table in the middle, that should be easy.
public class B
{
public virtual string Name { get; set; }
public virtual IList<A> AList { get; private set; }
}
Your query simply becomes...
var result = Session.Linq<B>()
.Where(b => b.AList.Count > 0)
.Select(b => new { b.Name, b.AList.Count }
.ToList();
Which produces very efficient SQL from Linq (using a count) and gives the same result.

Resources