The Entity Framework has a function with this signature:
public EntityTypeConfiguration<TEntityType> HasKey<TKey>(Expression<Func<TEntityType, TKey>> keyExpression);
If your table has a clustered primary key you can represent that like this:
this.HasKey(t => new { t.Field1, t.Field2 });
My question is, how are they consuming this anonymous type? I would like to build some similar functionality in methods of my own, that allow a lambda expression that returns multiple properties.
Is there some special way to peek into an anonymous type?
They just use reflection.
For additional performance, you can use expression trees to store pre-compiled delegates in a generic type.
Related
I want to have a class that has a number of fields such as String, Boolean, etc and when the class is constructed I want to have a fieldname associated with each field and verify the field (using regex for strings). Ideally I would just like specify in the constructor that the parameter needs to meet certain criteria.
Some sample code of how :
case class Data(val name: String ..., val fileName: String ...) {
name.verify
// Access fieldName associated with the name parameter.
println(name.fieldName) // "Name"
println(fileName.fieldName) // "File Name"
}
val x = Data("testName", "testFile")
// Treat name as if it was just a string field in Data
x.name // Is of type string, does not expose fieldName, etc
Is there an elegant way to achieve this?
EDIT:
I don't think I have been able to get across clearly what I am after.
I have a class with a number of string parameters. Each of those parameters needs to validated in a specific way and I also want to have a string fieldName associated with each parameter. However, I want to still be able to treat the parameter as if it was just a normal string (see the example).
I could code the logic into Data and as an apply method of the Data companion object for each parameter, but I was hoping to have something more generic.
Putting logic (such as parameter validation) in constructors is dubious. Throwing exceptions from constructors is doubly so.
Usually this kind of creational pattern is best served with one or more factory methods or a builder of some sort.
For a basic factory, just define a companion with the factory methods you want. If you want the same short-hand construction notation (new-free) you can overload the predefined apply (though you may not replace the one whose signature matches the case class constructor exactly).
If you want to spare your client code the messiness of dealing with exceptions when validation fails, you can return Option[Data] or Either[ErrorIndication, Data] instead. Or you can go with ScalaZ's Validation, which I'm going to arbitrarily declare to be beyond the scope of this answer ('cause I'm not sufficiently familiar with it...)
However, you cannot have instances that differ in what properties they present. Not even subclasses can subtract from the public API. If you need to be able to do that, you'll need a more elaborate construct such as a trait for the common parts and separate case classes for the variants and / or extensions.
I am wondering why GroupBy works with anonymous types.
List<string> values = new List<string>();
values.GroupBy(s => new { Length = s.Length, Value = s })
Anonymous types do not implement any interfaces, so I am confused how this is working.
I assume that the algorithm is working by creating an instance of the anonymous type for each item in the source and using hashing to group the items together. However, no IEqualityComparer is provided to define how to generate a hash or whether two instances are equal. I would assume, then, that the Object.Equals and Object.GetHashCode methods would be the fallback, which rely on object identity.
So, how is it that this is working as expected? And yet it doesn't work in an OrderBy. Do anonymous types override Equals and GetHashCode? or does the underlying GroupBy algorithm do some magic I haven't thought of?
As per the documentation, an anonymous type is a reference type:
From the perspective of the common language runtime, an anonymous type is no different from any other reference type.
Therefore, it will be using the default implementation for those functions as implemented by System.Object (which at least for equality is based on referential equality).
EDIT: Actually, as per that same first doco link it says:
Because the Equals and GetHashCode methods on anonymous types are defined in terms of the Equals and GetHashcode methods of the properties, two instances of the same anonymous type are equal only if all their properties are equal.
http://msdn.microsoft.com/en-us/library/bb397696.aspx
This link explains that GetHashCode and Equals are overridden.
It doesn't work on OrderBy because the new object does not implement IComparable.
I use in my project a lot of LINQ queries and business methods.
To allow these business method to be used from an Iqueryable :
I defined UDF functions in SQL Server (with the needed parameters)
Add this UDF to the EDMX model of the application
And make a gateway between UDF and LinQ with a method like this in a
partial class who inherits from the dbcontext :
[EdmFunction("MyProject.Store", "GetTaxesOfProduct")]
public static Decimal GetTaxesOfProduct(Decimal amount, Int32 TaxMethod)
{
throw new NotSupportedException("Not direct access possible, use with E-SQL or LINQ");
}
This works perfectly for IQueryable.
But the problem is that, to use this method from a simple object (not linked to a database record), i need to make something creepy like this :
var query = from foo in context.JustATable select context.GetTaxesOfProduct(15.55, 3);
And recently i came across this http://blogs.msdn.com/b/charlie/archive/2008/01/31/expression-tree-basics.aspx who explain how, with expression, you can make a method who is usable from C# objects and IQueryable
So, with expression, is it possible to make business methods like my method but without the use of UDF and just expressions ?
Thank you by advance !
It depends on the content of your UDF. Expression can work only with entities defined in your model and use only operations provided by Entity Framework provider for your database. So if you use any complex SQL statement with not supported equivalent for LINQ or non mapped features inside your UDF it will not work.
I have a semi complicated question regarding Entity Framework4, Lambda expressions, and Data Transfer Objects (DTO).
So I have a small EF4 project, and following established OO principles, I have a DTO to provide a layer of abstraction between the data consumers (GUI) and the data model.
VideoDTO = DTO with getters/setters, used by the GUI
VideoEntity = Entity generated by EF4
My question revolves around the use of the DTO by the GUI (and not having the GUI use the Entity at all), combined with a need to pass a lambda to the data layer. My data layer is a basic repository pattern with Add. Change, Delete, Get, GetList, etc.
Trying to implement a Find method with a signature like so:
public IEnumerable<VideoDTO> Find(Expression<Func<VideoEntity, bool>> exp)
...
_dataModel.Videos.Where(exp).ToList<Video>()
---
My problem/concern is the "exp" needing to be of type VideoEntity instead of VideoDTO. I want to preserve the separation of concerns so that the GUI does not know about the Entity objects. But if I try to pass in
Func<VideoDTO, bool>
I cannot then do a LINQ Where on that expression using the actual data model.
Is there a way to convert a Func<VideoDTO,bool> to a Func<VideoEntity, bool>
Ideally my method signature would accept Func<VideoDTO, bool> and that way the GUI would have no reference to the underlying data entity.
Is this clear enough? Thanks for your help
Thanks for the repliesto both of you.
I'll try the idea of defining the search criteria in an object and using that in the LINQ expression. Just starting out with both EF4 and L2S, using this as a learning project.
Thanks again!
In architectures like CQRS there isn't need for such a conversion at all cause read & write sides of app are separated.
But in Your case, You can't runaway from translation.
First of all - You should be more specific when defining repositories. Repository signature is thing You want to keep explicit instead of generic.
Common example to show this idea - can You tell what indexes You need in Your database when You look at Your repository signature (maybe looking at repository implementation, but certainly w/o looking at client code)? You can't. Cause it's too generic and client side can search by anything.
In Your example it's a bit better cause expression genericness is tied with dto instead of entity.
This is what I do (using NHibernate.Linq, but the idea remains)
public class Application{
public Project Project {get;set;}
}
public class ApplicationRepository{
public IEnumerable<Application> Search(SearchCriteria inp){
var c=Session.Linq<Application>();
var q=c.AsQueryable();
if(!string.IsNullOrEmpty(inp.Acronym))
q=q.Where(a=>a.Project.Acronym.Contains(inp.Acronym));
/*~20 lines of similar code snipped*/
return q.AsQueryable();
}
}
//used by client
public class SearchCriteria{
public string Acronym{get;set;}
/*some more fields that defines how we can search Applications*/
}
If You do want to keep Your expressions, one way would be to define dictionary manually like this:
var d=new Dictionary<Expression<Func<VideoDTO,object>>,
Expression<Func<VideoEntity,object>>{
{x=>x.DtoPropNumberOne,x=>x.EntityPropNumberOne} /*, {2}, {3}, etc.*/
};
And use it later:
//can You spot it?
//client does not know explicitly what expressions dictionary contains
_dataModel.Videos.Where(d[exp]).ToList<Video>();
//and I'm not 100% sure checking expression equality would actually work
If You don't want to write mapping dictionary manually, You will need some advanced techniques. One idea would be to translate dto expression to string and then back to entity expression. Here are some ideas (sorting related though) that might help. Expressions are quite complicated beasts.
Anyway - as I said, You should avoid this. Otherwise - You will produce really fragile code.
Perhaps your design goal is to prevent propagation of the data model entities to the client tier rather than to prevent a dependency between the presentation layer and data model. If viewed that way then there would be nothing wrong with the query being formed the way you state.
To go further you could expose the searchable fields from VideoEntity via an interface (IVideoEntityQueryFields) and use that as the type in the expression.
If you don't want to add an interface to your entities then the more complicated option is to use a VideoEntityQuery object and something that translates an Expression<Func<VideoEntityQuery,bool>> to an Expression<Func<VideoEntity,bool>>.
Caveat emptor, I'm new to Linq To SQL.
I am knocking up a prototype to convert an existing application to use Linq To SQL for its model (it's an MVVM app). Since the app exists, I can not change its data model.
The database includes information on events; these are either advertising events or prize events. As such, the data model includes a table (Event) with two associated tables (AdvertisingEvent and PrizeEvent). In my old C# code, I had a base class (Event) with two subclasses (AdvertisingEvent and PrizeEvent) and used a factory method to create the appropriate flavour.
This can not be done under Linq to SQL, it does not support this inheritance strategy.
What I was thinking of doing is creating an interface (IEvent) to includes the base, shared functionality (for example, a property "Description' which is implemented in each subclass). I thought I'd then add a propery to the superclass, for example SharedStuff, that would either return an AdvertisingEvent or PrizeEvent as a IEvent. From WPF I could then bind to MyEvent.SharedStuff.Description.
Does this make sense? Is there a better way to do this?
BTW: I'd rather not have to move to Linq to Entities.
You could always use interface inheritance to accomplish this. Instead of working with subclasses, have your IEvent interface, with the IPrizeEvent and IAdvertisingEvent interfaces deriving from that.
Then, work in terms of the interfaces.
You could then have separate implementations that don't derive from each other, but implement the appropriate interfaces.
Also, the nice side effect of working with interface inheritance in LINQ-to-SQL is if you have methods that operate on IQueryable<T> where the constraint on T is IEvent, you can do something like this:
// Get an IQueryable<AdvertisingEvent>
IQueryable<AdvertisingEvent> events = ...;
// A function to work on anything of type IEvent.
static IQueryable<T> FilteredEvents<T>(this IQueryable<T> query,
string description)
where T : class, IEvent
{
// Return the filtered event.
return query.Where(e => e.Description == description);
}
And then make the call like this:
events = events.FilteredEvents("my description");