Associations in DLinq Select() extension method

A

Andrus

I tried to use association property in Marc Select() extension method but
got exception
in Bind() call

Property 'Customer.ContactName' is not defined for type 'nwind.Order'"

How to fix ?

Andrus.

Northwind northwind = CreateDB();
var orders = northwind.GetTable<Order>();
var q = orders.Select(
new string[] {"OrderID",
"Customer.ContactName" });

// should generate:
//var q = from order in orders
// select new {
// order.OrderID,
// order.Customer.ContactName
// };
var list = q.ToList();

// Extension methor created by Marc Gravell
public static class SelectUsingSingleProjection {

public static IQueryable<T> Select<T>(this IQueryable<T> source, params
string[] propertyNames)
where T : new() {

if (source == null) throw new ArgumentNullException("source");
if (propertyNames == null) throw new
ArgumentNullException("propertyNames");

Type type = typeof(T);
var sourceItem = Expression.Parameter(type, "t");
var newExpr = Expression.New(type.GetConstructor(Type.EmptyTypes));
var bindings = propertyNames.Select<string, MemberBinding>(
name => Expression.Bind(
type.GetProperty(name),
Expression.Property(sourceItem, name))
).ToArray();

return source.Select(Expression.Lambda<Func<T, T>>(
Expression.MemberInit(newExpr, bindings), sourceItem));
}
 
M

Marc Gravell

How to fix ?

Write it the way that you know works... (i.e. the one you commented
out), or write that parses the input string doing a Split on '.', and
uses reflection to navigate the child hierarchy. Which isn't something I
have time to do right now...

Marc
 
A

Andrus

Marc,
Write it the way that you know works... (i.e. the one you commented out),

Columns can be specified by user at runtime. So I cannot hard-code them into
code.
I can try to create separate assembly containing this query at runtime and
compile it dynamically.
Is this reasonable ?
or write that parses the input string doing a Split on '.', and uses
reflection to navigate the child hierarchy. Which isn't something I have
time to do right now...

I'm unable to implement it using reflection: I do'nt have enough deep
knowledge about expression tree.

Where to find GetProperty() method which accepts dotted notation and
traveres through object tree ?
Such method should be very useful in may cases. Is this present in .NET
framework ?
Is it possible to use MS Dynamic Linq Library Expression
evaluator for this ?

Andrus.
 
M

Marc Gravell

I'm unable to implement it using reflection: I do'nt have enough deep
knowledge about expression tree
Depending on your urgency, I might be able to look at this, but it won't
be "now"...
Where to find GetProperty() method which accepts dotted notation and
traveres through object tree ?
Such method should be very useful in may cases. Is this present in .NET
framework ?
Well, the binding code does something like this, but not in a way that
would be easy to use...
Is it possible to use MS Dynamic Linq Library Expression
evaluator for this ?
I have no idea.
 
A

Andrus

Marc,
Depending on your urgency, I might be able to look at this, but it won't
be "now"...

If you have some time in future it would be very useful.
Maybe it would be useful to add this function to MiscUtil library.

Andrus.
 
J

Jon Skeet [C# MVP]

If you have some time in future it would be very useful.
Maybe it would be useful to add this function to MiscUtil library.

I don't think so. I see this as part of what the LINQ provider should
be doing for you. Again, it looks like DLinq isn't really ready for
everything you want it to do.

Jon
 
M

Marc Gravell

I don't think so.

I strongly agree; this is not a MiscUtil thing - and besides, Jon owns
that, not me - I just happened to contribute a small part...

But the fact remains, you seem to have a rather unique take on what LINQ
should do... and if it can't do it, you try to do it anyway (or you try
to get others?me? to)... from a support perspective, that is never a
good idea.

Marc
 
M

Marc Gravell

OK; I've had a few moments to think, and I've reached un unavoidable
conclusion. From "day dot", people (myself and many others) have
repeatedly told you that your design works in an unorhadox manner, that
wasn't really directly suited to LINQ. And warned that at each stage you
were going to hit problems.

Well, sure enough; at each stage, you've hit problems; and perhaps
foolishly I've assisted with each successive issue because *considered
individually* it was only a small problem, that could be worked around.

Well; putting a while series of little problems one after the other is
just an endless cycle.

I don't mean to be obstructive, but I have to draw the line eventually;
I'm not simply here to unpick this one system, and there are better
things (for myself, my company, and the community) that I could do with
my time.

So: sorry, but I won't be looking at "supporting dots" in property
lookups. I hope you understand; it isn't personal.

But any more general C# / .NET etc questions, and I'm all ears.

Marc
 
A

Andrus

Jon,
I don't think so. I see this as part of what the LINQ provider should
be doing for you.

LINQ provider should consume expression trees, not to create it.
So I still think this should be task of dynamic generic linq library which
can
then used with any provider.

MS Dynamic Linq Library return non-generic IQueryable.

Again, it looks like DLinq isn't really ready for
everything you want it to do.

DLinq ( = DataBase LINQ) is used as common denominator to refer all linq
providers which allow to retrieve database data.
I have seen such usage in MS blogs.

If we need to refer to specific provider, we can use this provider name like
DbLinq, Ling-SQL
etc.

Andrus.
 
M

Marc Gravell

DLinq ( = DataBase LINQ) is used as common denominator to refer all linq
providers which allow to retrieve database data.

When I see DLinq, I read "LINQ to SQL"; which is why it sometimes get
especially confusing when talking about DLinq (one of the MS
offerings) and DbLinq (one of the alternatives).

By the way, MS are apparently investigating the "connect" issue with
the cache. I'll keep you posted of any updates.

Marc
 
J

Jon Skeet [C# MVP]

Andrus said:
LINQ provider should consume expression trees, not to create it.

But the C# compiler is already creating an expression tree, isn't it?
Maybe I've missed something about what you're trying to do in the first
place...
So I still think this should be task of dynamic generic linq library which
can then used with any provider.

MS Dynamic Linq Library return non-generic IQueryable.



DLinq ( = DataBase LINQ) is used as common denominator to refer all linq
providers which allow to retrieve database data.

Not in my experience. I understand DLinq as another name for LINQ to
SQL - although I misread the subject of your post as DbLinq rather than
DLinq, which doesn't help things.
I have seen such usage in MS blogs.

If we need to refer to specific provider, we can use this provider name like
DbLinq, Ling-SQL
etc.

And does LINQ to SQL not handle this case?
 
J

Jon Skeet [C# MVP]

Andrus said:
I tried to use association property in Marc Select() extension method but
got exception in Bind() call

Property 'Customer.ContactName' is not defined for type 'nwind.Order'"

How to fix ?

<snip>

Okay, I've now reread this original post, and you're right - it's not
something the provider should need to cope with. It *could* be put into
MiscUtil, although I don't think it's really worth it. It seems to be
avoiding half the point of LINQ to start with.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top