Sometimes you need to define some business rules and the Specification pattern is a useful tool. For example:
public class CanBorrowBooksSpec : ISpecification<Customer>
{
public bool Satisfies(Customer customer)
{
return customer.HasLibraryCard
&& !customer.UnpaidFines.Any();
}
}
However, I often find that I need to 'push' these rules into SQL to improve performance or to cater for things like paged lists of records.
I am then left with having to write code for the rules twice, once in CLR code, and once in SQL (or ORM language).
How do you go about organising code like this?
It seems best if the code was kept together in the same class. That way, if the developer is updating the business rules they have less chance of forgetting to update both sets of code. For example:
public class CanBorrowBooksSpec : ISpecification<Customer>
{
public bool Satisfies(Customer customer)
{
return customer.HasLibraryCard
&& !customer.UnpaidFines.Any();
}
public void AddSql(StringBuilder sql)
{
sql.Append(#"customer.HasLibraryCard
AND NOT EXISTS (SELECT Id FROM CustomerUnpaidFines WHERE CustomerId = customer.Id)");
}
}
However this seems quite ugly to me as we are now mixing concerns together.
Another alternative would be using a Linq-To-YourORM solution, as the LINQ code could either be run against a collection, or it could be translated into SQL. But I have found that such solutions are rarely possible in anything but the most trivial scenarios.
What do you do?
We used Specification pattern with Entity Framework. Here's how we approached it
public interface ISpecification<TEntity>
{
Expression<Func<TEntity, bool>> Predicate { get; }
}
public class CanBorrowBooksSpec : ISpecification<Customer>
{
Expression<Func<Customer, bool>> Predicate
{
get{ return customer => customer.HasLibraryCard
&& !customer.UnpaidFines.Any()}
}
}
Then you can use it against LINQ-to-Entities like
db.Customers.Where(canBorrowBooksSpec.Predicate);
In LINQ-to-Objects like
customerCollection.Where(canBorrowBooksSpec.Predicate.Compile());
Related
Task: write a generic extension for Entity Framework entities
I am not sure if this is even possible due to the fact that each entity usually will have differing properties, but I have a group of entities that share a few common properties and all I was wondering if it is even possible to build a generic extension instead of always having to write out the same code for each entity.
I spent a bit of time researching this, but there is not much , which leads me to believe this just is not possible.
Anyway, contrary to my better judgment I am going to ask a stupid question on StackOverFlow.
This is what I was thinking, but obviously a non compile-able example, but at least you will get the idea.
public static List<TEntity> Generic<TEntity>(this DbContext db, string name)
{
return db.TEntity.Where(s => s.Name == name);
}
I poke in the right direction would be appreciated.
And just for clarity, I have never spent a single hour in a classroom for programming, I am self taught, so if it is not possible to this, could the answer explain please explain technically why this is not possible in Entity Framework. As I could not find anything substantial myself.
Thanks to #Bagus Tesa, I was able to solve this.
As Bagus tesa states, make an interface that references the common properties of the Entities and refference the interface with the Entities and make an extension that way.
The code I used,
public static IQueryable<IFilterEntity> FilterEntity(this BaseViewModel vm,
IQueryable<IFilterEntity> list)
{
return list.Where(s => s.Name == vm.name &&
s.DateMonth == vm.Month &&
s.DateYear == vm.Year);
}
The interface,
public interface IFilterEntity
{
string Name { get; set; }
int? DateYear { get; set; }
int? DateMonth { get; set; }
}
The BaseViewModel,
public class BaseViewModel
{
string Name => RootVm.Name;
int? DateYear => RootVm.SelectedDate.Month;
int? DateMonth => RootVm.SelectedDate.Month;
}
Thanks for all the help with. And I hope this helps someone else.
Use this
public IEnumerable<TEntity> Filter(Expression<Func<TEntity, bool>> filter, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null)
{
db.Set<TEntity>().AsNoTracking().AsQueryable().Where(filter);}
I'm not really sure how to express what I'm trying to achieve without showing some pseudo-code to the effect -
Assuming the following DTO is defined:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
We have 2 different custom IQueryable<T> classes defined:
public class InnerQueryable<T> : IQueryable<T>
{
// ...
}
public class OuterQueryable<T> : IQueryable<T>
{
public OuterQueryable(IQueryable<T> inner)
{
// Assign `inner` to a local variable to be used in `IQueryable<T>` impl.
// ...
}
// ...
}
NOTE: OuterQueryable<T> is designed to extend the behavior of any other IQueryable<T> type by wrapping it.
And a rather naive extension method to allow OuterQueryable<T> implementations to be created simply:
public static IQueryable<T> ToOuterQueryable<T>(this IQueryable<T> inner /*, ... */)
{
// Assume `OuterQueryable<T>` has a constructor that takes another `IQueryable<T>`.
return new OuterQueryable<T>(inner /*, ... */);
}
Given an expression as shown below, is there any way for the InnerQueryable<T> instance to find out which specific properties are selected once the query is wrapped by OuterQueryable<T>?
InnerQueryContext.AsQueryable<Person>().Where(p => p.Age > 30)
.ToOuterQueryable().Select(p => new
{
p.FirstName,
p.LastName
};
Is there anyway for InnerQueryable<T> to know that the query built on
OuterQueryable<T> returned only Person.FirstName and Person.LastName?
If it helps to show the context, I have a WCF data service that returns our internal entity, but I need the ability to know which specific members of the internal entity were returned from the service. WCF DS defines the OuterContext<T> in this case and I haven't identified a way to intercept the response post-projection to tell me what I'm looking for.
Any ideas would be welcome.
UPDATE: What are InnerQueryable<T> and OuterQueryable<T>?
The answer to that is fairly involved if you aren't familiar with the architecture of WCF Data Services, but here it goes:
In WCF Data Services, a service exposes IQueryable<T> properties to a DataServiceProvider implementation (i.e. EntityFrameworkDataServiceProvider, ReflectionDataServiceProvider, or a custom DataServiceProvider implementation that implements the necessary interface(s)).
These core IQueryable<T> properties act as the foundation of resources exposed through the service, and are built upon using the composable nature of LINQ queries. A simple example using the Person entity above would look like:
public class SimpleContext
{
public IQueryable<Person> People
{
get
{
return new[] {
new Person { FirstName = "George", LastName = "Jetson", Age = 43 },
new Person { FirstName = "Elroy", LastName = "Jetson", Age = 7 }
}.AsQueryable();
}
}
}
This SimpleContext would then be referenced by a simple data service implementation:
public class SimpleDataService : DataService<SimpleContext>
{
// InitializeService method and others...
}
Now when I query the data service passing a projection:
http://localhost/SimpleDataService/People()?$select=FirstName,LastName
The framework will take the IQueryable<Person> returned from SimpleDataContext.People and pass it through an internal IQueryProvider/IQueryable implementation that understands how to generate an expression tree from the query string parameters and then compose another query using the IQueryable<Person> as its source.
Conceptually though, my original question above describes how to replicate the behavior without having to worry about all of the WCF data services stuff.
I still don't quite understand why would WCF DS need that OuterQueryable. What it needs to do is to parse the query and then call your InnerQueryable based on that.
If there indeed is some kind of wrapper around your InnerQueryable, then it's entirely up to that wrapper to decide what your wrapper queryable will be able to see.
Consider two trivial implementations of the wrapper: if the wrapper simply forwards each method call to the wrapped object, then you will be able to see everything directly. On the other hand, if the wrapper doesn't do anything at all, then there is no way for you to observe anything at all.
Let's say I have an interface called IConvertableModel and it helps me to convert some MVC models to/from DTO objects as shown below:
public class DisplayEditModel : IConvertableModel<Display>
{
[HiddenInput(DisplayValue = false)]
public int ObjectId { get; set; }
[StringLength(255)]
public string Description { get; set; }
public Display ToDto()
{
return new Display
{
Description = Description,
ObjectId = ObjectId,
};
}
public void SetFromDto(Display dto)
{
Description = dto.Description;
ObjectId = dto.ObjectId;
}
}
But there is one problem with this approach and that is it doesn't allow me do this :
var dto = _dtoRepository.GetFirstDto();
return new DisplayEditModel().SetFromDto(dto);
Instead I should do the following:
var dto = _dtoRepository.GetFirstDto();
var model = new DisplayEditModel();
model.SetFromDto(dto);
return model;
and this is adding extra two lines of code and little bit complexity in the long run.
What I am thinking is to convert SetFromDto method to something like this:
public DisplayEditModel SetFromDto(Display dto)
{
Description = dto.Description;
ObjectId = dto.ObjectId;
return this;
}
I think the benefit of this code is obvious but I also like to learn whether this harms code readability and leads to unexpected results for developers in the long run and if you think anything else, what would you recommend.
Note: Because of the interfaces reasons, I am not thinking to implement a constructor method.
A few thoughts, to begin with:
Adding lines of code is not the same as adding complexity. Having three statements, where each does a simple operation, is not necessarily harder to maintain or understand than a single statement with three operations inside of it.
When a method that begins with Set..., programmers will automatically assume that some stateful values of the target object are going to be changed by this method. It is rare for Set methods to have a return value. Property setters in C# actually "return" the original value passed into them, so you can chain setters:
int i = foo.A = 2;
So the precedent is generally against returning "this" from a set method specifically.
Chaining in general is most useful/desired when you're expecting several operations to be performed, one after the other. For example, C# provides nice initialization syntax so you can "chain" a bunch of different property setters on the same object:
var foo = new Foo { A = 1, B = 2 };
You can see how chaining is fulfilling the need to perform similar, grouped, repetitive operations that typically get performed all together. That is not the problem that you are trying to solve.
If your main gripe is that you don't like having three lines of code, why not just use a helper whose name indicates what you're trying to do?
TModel MapToModel<TModel, TDto>(TDto dto, TModel model)
where TModel : IConvertableModel<TDto>
{
model.SetFromDto(dto);
return model;
}
// usage:
var dto = _dtoRepository.GetFirstDto();
return MapToModel(dto, new DisplayEditModel());
... or even:
TModel CreateModel<TModel, TDto>(TDto dto)
where TModel : IConvertableModel<TDto>, new()
{
var model = new TModel();
return MapToModel(dto, model);
}
// usage:
var dto = _dtoRepository.GetFirstDto();
return CreateModel<DisplayEditModel>(dto);
This is simple, readable, and feasible, whereas the approach you're suggesting would break the IConvertableModel<Display> interface:
public interface IConvertableModel<TDto>
{
public TDto ToDto();
public ??? SetFromDto(TDto dto);
}
What would SetFromDto return? You would have to define another generic type on IConvertableModel.
public interface IConvertableModel<TDto, TModel> {
public TDto ToDto();
public TModel SetFromDto(TDto dto);
}
But this wouldn't really indicate that the SetFromDto method is necessarily returning itself, because it allows for a class that is not a TModel to implement IConvertableModel to convert between two other types.
Now, you could go out of your way to push the generics even farther:
public interface IConvertableModel<TDto, TModel>
where TModel : IConvertableModel<TDto, TModel>
{...}
But this still allows for some fudging, and the interface cannot guarantee that you are really returning "this" object. All in all, I'm not a big fan of that approach.
Rather than having DisplayEditModel have a get/set method for a Display object to get/set the values, just use a property that doesn't actually have a separate backing store:
public Display Display
{
get
{
return new Display
{
Description = Description,
ObjectId = ObjectId,
};
}
set
{
Description = value.Description;
ObjectId = value.ObjectId;
}
}
Now you can use an object initializer with this property when creating a model:
return new DisplayEditModel() { Display = dto };
This is a very javascript way of approaching this problem, though it has it's benefits. In the context of C#, it is a little bit strange though libraries such as LINQ do this to allow chaining together function calls.
My only worry about this, is that this has to be a class that does this consistently. Implementing a chaining function return pattern is not really a convenience as much as it is a design choice. The rule to follow in this case, would be to return this every time you mutate the object.
Chaining also may not be worth it performance wise. Something that can be done by wrapping all those operations into a single function is much faster. For instance:
MyVector.setX(1).SetY(1).SetZ(1).SetW(0)
is a lot slower than simply
MyVector.set(1, 1, 1, 0)
because now you are now doing excessive stack operations to do something fairly simple. It only becomes worth it on very large operations that take up the bulk of the computing time and make sense to chain together. For this reason, LINQ allows you to chain things together.
I wouldn't say that it necessary "harms" or is dangerous. We are in the world of a managed language, so we don't have direct access to that memory location (unlike C/C++). So I would just call it a design choice which can be fairly powerful in some cases and not so much in others.
As noted, chainable methods work fine but are not as common in C# as in some other languages. If the extra lines of code only happen in one place, I'd just leave it alone. If it's really bugging you or you do it a lot, then consider implementing a special constructor for it:
public void DisplayEditModel(Display dto)
{
this.SetFrom(dto);
}
or a static factory method:
public static DisplayEditModel CreateFrom(Display dto)
{
var model = new DisplayEditModel();
model.SetFrom(dto);
return model;
}
Either option has a clear intent, lets you create and return the object in a single line, and is idiomatic. It does require a few extra lines of code in DisplayEditModel, but I doubt it will be a serious problem.
If I'm trying to filter results at multiple levels of an IEnumerable<T> object graph, is there a preferred way of chaining extension methods to do this?
I'm open to any extension method and lambda usage, but I'd prefer not to use LINQ syntax to remain consistent with the rest of the codebase.
Is it better to push the filtering to the selector of the SelectMany() method or just to chain another Where() method? Or is there a better solution?
How would I go about identifying the best option? In this test case, everything is directly available in memory. Obviously both samples below are currently producing the same correct results; I'm just looking for a reason one or the other (or another option) would be preferred.
public class Test
{
// I want the first chapter of a book that's exactly 42 pages, written by
// an author whose name is Adams, from a library in London.
public Chapter TestingIEnumerableTExtensionMethods()
{
List<Library> libraries = GetLibraries();
Chapter chapter = libraries
.Where(lib => lib.City == "London")
.SelectMany(lib => lib.Books)
.Where(b => b.Author == "Adams")
.SelectMany(b => b.Chapters)
.First(c => c.NumberOfPages == 42);
Chapter chapter2 = libraries
.Where(lib => lib.City == "London")
.SelectMany(lib => lib.Books.Where(b => b.Author == "Adams"))
.SelectMany(b => b.Chapters.Where(c => c.NumberOfPages == 42))
.First();
}
And here's the sample object graph:
public class Library
{
public string Name { get; set; }
public string City { get; set; }
public List<Book> Books { get; set; }
}
public class Book
{
public string Name { get; set; }
public string Author { get; set; }
public List<Chapter> Chapters { get; set; }
}
public class Chapter
{
public string Name { get; set; }
public int NumberOfPages { get; set; }
}
Which is best likely varies based on the LINQ implementation you're using. LinqToSql will behave differently from in-memory filtering. The order of the clauses should impact the performance depending on what data is used, since naive implementations will filter more records earlier in the sequence meaning less work for the later methods.
For your two examples, I would guess that the performance difference is negligible and would favor the first since it allows easier modification of each clause independent of the others.
As for determining the best option, it's the same as anything else: measure.
I'm guessing the first expression you have will be slightly but insignificantly faster. To really determine if one or the other is faster, you will need to time them, with a profiler or Stopwatch.
The readability doesn't seem to be strongly affected either way. I prefer the first approach, as it has less levels of nesting. It all depends on your personal preference.
It depends on how the underlying LINQ provider works. For LINQ to Objects, both in this case would require about the same amount of work, more or less. But that's the most straightforward (simplest) example, so beyond that it's hard to say.
This might give you a different angle, though it's more a matter of style...
I sometimes find myself doing something like this...
return libraries.Filter(
l => l.City == "",
l => l.Books,
b => b.Author == "Adams",
b => b.Chapters,
c => c.NumberOfPages == 42
);
...where you can guess what the extensiion is, something like...
public static IEnumerable<TC> Filter<TL, TB, TC>(this IEnumerable<TL> list,
Func<TL, bool> whereLs,
Func<TL, IEnumerable<TB>> selectBs,
Func<TB, bool> whereBs,
Func<TB, IEnumerable<TC>> selectCs,
Func<TC, bool> whereCs
)
{
return list
.Where(whereLs)
.SelectMany(selectBs)
.Where(whereBs)
.SelectMany(selectCs)
.Where(whereCs);
}
...or....
...
{
return list
.Where(whereLs)
.SelectMany(l => selectBs(l).Where(whereBs))
.SelectMany(b => selectCs(b).Where(whereCs));
}
And combinations / options are many, depending on what you have, how you 'like having your code' (abstract it some more or 'capture', 'parametrize' e.g. PerCityAuthorPages(_city, _author, _numPages); etc.)
...basically, I dislike having all the 'Where', 'Select'-s etc. and to me is not that readable (either).
While with the 'short form' it's quite clear which is which, where, select etc. and it's very much 'short-hand' and in much less chars.
Also, you can deffer the decision about Where/Select combinations for later (do one or the other based on the needs, provider)
And #Telastyn is quite right, LINQ providers, e.g. if you look at some implementation code,
with all the expressions reducing etc.
are pretty non-deterministic (i.e. from provider to provider) in a way they might end up mapping to e.g. SQL
though this should map the same in most I think.
Inspired by a desire to be able to use enumerations in EF queries, I'm considering adding an ExpressionVisitor to my repositories that will take incoming criteria/specifications criteria and rewrite them to use the corresponding persisted int property.
I'm consistently using the following Value-suffix pattern in my (code-first) entities:
public class User : IEntity
{
public long ID { get; set; }
internal int MemberStatusValue { get; set; }
public MemberStatus MemberStatus
{
get { return (MemberStatus) MemberStatusValue; }
set { MemberStatusValue = (int) value; }
}
}
And map this to the database using the following:
internal class UserMapping : AbstractMappingProvider<User>
{
public override void DefineModel( DbModelBuilder modelBuilder )
{
// adds ToTable and other general mappings
base.DefineModel( modelBuilder );
Map.Property( e => e.MemberStatusValue ).HasColumnName( "MemberStatus" );
}
}
In my repositories I have the following method:
public IQueryable<T> Query( Expression<Func<T, bool>> filter, params string[] children )
{
if( children == null || children.Length == 0 )
{
return Objects.Where( filter );
}
DbQuery<T> query = children.Aggregate<string, DbQuery<T>>( Objects, ( current, child ) => current.Include( child ) );
return filter != null ? query.Where( filter ) : query;
}
I'd like to add a method call inside this method to rewrite the filter expression, replacing all references to the MemberStatus property with references to MemberStatusValue.
I suppose it will be a solution involving something like seen in this SO post, but I'm not sure exactly how to get from idea to implementation.
If you can give any advice on the potential performance impact of adding this feature, that would also be appreciated.
I'm not sure whether this is quite what you're after, but I've found it simpler to handle enums in a similar but slightly different way. To wit, I have two properties, as you do, but my int property is public and is what the database persists; I then have another public "wrapper" property that gets/sets the int property value via casts from/to the desired enumerated type, which is what's actually used by the rest of the application.
As a result, I don't have to mess around with the model; EF understands and persists the int property just fine while the rest of the application gets nice interactions with the enum type. The only thing I don't like about my approach is that I have to write my LINQ statements with a bunch of casts on any enum value I'm trying to query to turn it into an int to match against the field that's actually persisted. It's a small price, however, and I'd like to suggest it to you because it appears to me that you're using a string to generate your query which gives up all the type safety, Intellisense, etc. that LINQ provides.
Finally, if you're interested in a walkthrough of how to use the new enum features in EF 5 (which is available in beta for download now if you'd like to try it out), check this out:
http://msdn.microsoft.com/en-us/hh859576