I want to pursue the concept of embedding lamdbas in custom attributes. It is not supported today to my knowledge but I believe could be very valuable for DLINQ and more.
public class Customer
{
[Association((c, o) => c.CustomerID == o.CustomerID && o.Status == OrderStatus.Incomplete)]
public Order[] IncompleteOrders;
}
I believe that a syntax such as this would generalize the join conditions that are supported by AssociationAttribute and allow for additional conditions. In that way, queries need not repeat those conditions.
Note that regardless of whether DLINQ adopts this, there is a deeper issue of supporting attribute properties of delegate type (in this case Func<P, F, bool>). This might touch the runtime and is thus off the table I presume.

Lambdas in Custom Attributes
JavierPrg
A significant benefit of this syntax is the elimination of the OtherKey property on [Association]. It is a weakly-typed reference to a property name. Clearly, a lambda can provide the same reference in a strongly-typed manner, and contributes to the main objective of LINQ to reduce weak typing.
Mikhail Podolski
The suggestion implies that the join conditions must be folded into the query. Today, DLINQ generates queries using only the WHERE clause (that is, pre-SQL92 syntax) for specifying join conditions. The modern JOIN..ON syntax could be used to precisely manifest the conditions specified on the [Association] attribute.
My point is that this separation of concerns might ease the generation work.
Saptagiri
I was having some back and forth conversations with Sonja Keserovic, one of the CLR PMs about this a few months ago, here's the product feedback suggestion:
http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx feedbackid=9c4af9f4-5717-4755-b715-53d7581ecf2b
Partially this was for AOPish style injection (preconditions, logging, instrumentation), however there are a large number of applications.
The current Expression model in LINQ is immutable, once an expression tree has been created you cannot modify it other than creating a new tree.
Structs cannot be const, only the intrinsic types and strings support const:
http://msdn.microsoft.com/library/en-us/csspec/html/vclrfcsharpspec_10_3.asp (10.3 Const declaration)
http://msdn.microsoft.com/library/default.asp url=/library/en-us/csspec/html/vclrfcsharpspec_4_1.asp (4.1 Value Types)
Static readonlys also cannot be passed to Attributes, e.g. you must use "" and not string.Empty.
A Token to a method or methodhandle could be passed to an attribute however this information is only known at compile time by the compiler, therefore having the compiler interpret a lambda to a static readonly expression tree and some hidden internal retrieval method referenced by a token is entirely plausible.
MarkGrant
Phoenix blog starting up: http://blogs.msdn.com/kangsu/archive/2005/11/01/487914.aspx
Roberto Santos
But I agree, less-than-optimal syntax.
Co&#235;ndou
> {
> [Association((c, o) => c.CustomerID == o.CustomerID && o.Status > == OrderStatus.Incomplete)]
> public Order[] IncompleteOrders;
> }
Where do the parameters c and o come from How does compiler knows, that c is of type Customer and o of type Order
bertcord
Compiler enhancements: Sounds like what I imagine Phoenix would do. What did Abrams have to say
infrandom
This shouldn't be a problem, and it's looking much better than the strings.
Ahmed Amin El-Morali
I like the idea of specifying join conditions as expression trees.< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
I’ve created a test copy of the project, we create at my firm, and start to replace our ORM classes and database access through them with DLinq.
I’m already stuck with the problem, that I can’t add some extra condition to association condition (like “o.Status == OrderStatus.Incomplete” in the example above).
So I have my proposal. If we can’t use expression trees in attributes, then why not create the expressions as static read-only variables, and in the attribute specify the name of the variable
Something like this:
class AssociationCondition<ThisType, OtherType>
where ThisType : class
where OtherType : class
{
public AssociationCondition(
Expression<Func<ThisType, OtherType, bool>> innerJoinCondition)
{
}
public AssociationCondition(
Expression<Func<ThisType, OtherType, bool>> innerJoinCondition,
Expression<Func<OtherType, bool>> whereCondition)
{
}
}
class Customer
{
[Column]
public string CustomerID;
private static readonly AssociationCondition<Customer, Order>
AllOrdersCondition = new AssociationCondition<Customer, Order>(
(c, o) => c.CustomerID == o.CustomerID
);
private static readonly AssociationCondition<Customer, Order>
IncompleteOrdersCondition = new AssociationCondition<Customer, Order>(
(c, o) => c.CustomerID == o.CustomerID,
o => o.OrderStatus == OrderStatus.Incomplete
);
[Association(Condition = "AllOrdersCondition") /* and other properties*/]
EntitySet<Order> _AllOrders;
[Association(Condition = "IncompleteOrdersCondition")]
EntitySet<Order> _IncompleteOrders;
}
class Order
{
[Column]
public string CustomerID;
[Column]
public OrderStatus OrderStatus;
}
enum OrderStatus
{
Incomplete
}
bdee1
When you declare an attribute that takes in a Type argument and use typeof() the compiler injects the RuntimeTypeHandle for the type as if it were a constant, making that a legal case.
An expression tree is not a constant, and therefore could not be part of an attribute argument. The RuntimeMethodHandle to the generated delegate for a lambda could be passed, but might defeat the need to place an expression tree.
The custom compiler could inject a static method that returns Expression for the expression tree and pass in the RuntimeMethodHandle for the static method to the argument and that is a possiblity, but as to whether that is a legal implementation I am unsure.
Andy_Webber_
This should be completely feasible, given that attributes are themselves classes, and an attribute use leads to an instantiation.
Other uses I can see: validation, pre- and post- conditions, etc.
Federico_Star
I was talking with Abrams at PDC about a CLR or compiler enhancement for 3.0 for a Compile-Time attribute that could inject code before, inside and after any signature at compile time that could possibly perform the same type of thing
Brian Merz
public class Customer
{
[Association<Customer, Order>((c, o) => c.CustomerID == o.CustomerID && o.Status >= OrderStatus.Incomplete)]
public Order[] IncompleteOrders;
}
snymanr
Re static readonly: static readonly != immutable, which may be a source of that problem.
Re const: I remember now.. Const are inlined. Can't do that with something that may contain a ref field and expect the ref to be maintained.
Of course, I don't know the issues deep enough to know why one couldn't load a tree into an attribute.