I have tried to get source running as explained in http://eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_fetchgroup.htm
#FetchGroup(name="names",
attributes={
#FetchAttribute(name="firstName"),
#FetchAttribute(name="lastName")
})
TypedQuery query = em.createQuery("SELECT e FROM Employee e", Employee.class);
query.setHint(QueryHints.FETCH_GROUP_NAME, "names");
Sadly it ends up with "Needs to implement FetchGroupTracker".
I don't know if it is really the case or I'm missing something. Does anybody know where I can find a sample for it?
You must set up byte code weaving/enhancement for this to work automatically, otherwise your entities will need to implement the FetchGroupTracker class so that the fetch group attributes can be put into and used by your entity. See https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving
Related
I want to create queries using EF FromSqlInterpolated or FromSqlRaw that allows me to use Like clauses, but I don't know what is the right way to do it without opening the application to SqlInjection attacks.
One first approach has took me to the following code
var results = _context.Categories.FromSqlInterpolated(
$"Select * from Category where name like {"%" + partialName + "%"}");
First test worked fine, it returns results when providing expected strings, and returns nothing when i provide something like ';select * from Category Where name='Notes'--%';
Still I don't know much about SqlInjection, at least not enough to feel safe with the query shown before.
Does someone know if the query is safe, or if there is a right way to do it?
Thanks
From this document
The FromSqlInterpolated and ExecuteSqlInterpolated methods allow using
string interpolation syntax in a way that protects against SQL injection attacks.
var results = _context.Categories.FromSqlInterpolated(
$"Select * from Category where name like {"%" + partialName + "%"}");
Or you can also change your query to Linq-to-Entity like this way
var results = _context.Categories.Where(p => p.name.Contains(partialName ));
I was having some performance issues using SharpRepository, and after playing around the SQL Query Profiler I found the reason.
With EF I can do stuff like this:
var books = db.Books.Where(item => item.Year == '2016');
if (!string.IsNullorEmpty(search_author))
books = books.Where(item => item.Author.Contains(search_author);
return (books.ToList());
EF will not really do anything until books is used (last line) and then it will compile a query that will select only the small set of data matching year and author from the db.
But SharpRepository evaluates books at once, so this:
var books = book_repo.Books.FindAll(item => item.Year == '2016');
if (!string.IsNullorEmpty(search_author))
books = books.Where(item => item.Author.Contains(search_author);
return (books.ToList());
will compile a query like "select * from Books where Year == '2016'" at the first line, and get ALL those records from the database! Then at the second line it will make a search for the author within the C# code... That behaviour can be a major difference in performance when using large databases, and it explains why my queries timed out...
I tried using repo.GetAll().Where() instead of repo.FindAll().... but it worked the same way.
Am I misunderstanding something here, and is there a way around this issue?
You can use repo.AsQueryable() but by doing that you lose some of the functionality that SharpRepository can provide, like caching or and aspects/hooks you are using. It basically takes you out of the generic repo layer and lets you use the underlying LINQ provider. It has it's benefits for sure but in your case you can just build the Predicate conditionally and pass that in to the FindAll method.
You can do this by building an Expression predicate or using Specifications. Working with the Linq expressions does not always feel clean, but you can do it. Or you can use the Specification pattern built into SharpRepository.
ISpecification<Book> spec = new Specification<Book>(x => x.Year == 2016);
if (!string.IsNullorEmpty(search_author))
{
spec = spec.And(x => x.Author.Contains(search_author));
}
return repo.FindAll(spec);
For more info on Specifications you can look here: https://github.com/SharpRepository/SharpRepository/blob/develop/SharpRepository.Samples/HowToUseSpecifications.cs
Ivan Stoev provided this answer:
"The problem is that most of the repository methods return IEnumerable. Try repo.AsQueryable(). "
I have an existing app that I am trying to upgrade from MVC5/EF6 to MVC6/EF7. We dynamically create some of our SQL tables, and as a result, have made use of the
System.Data.Entity.Database.SqlQuery
method to automatically map to entities that we use throughout our application.
This method seems to have gone away (i.e. not part of
Microsoft.Data.Entity.Infrastructure.Database ) in EF7 (or is not yet implemented). Are there plans to re-implement this method in EF7 or is there another way to accomplish this? Our project is kind of dead in the water until we figure this out.
Edited on May 20, 2015
I've been trying to make this work with FromSql, since that's what's available in Beta4, but no matter what combination of concatenated string, parameters I try, I keep getting different versions of an "Incorrect Syntax near #xxxvariable" message.
var results = Set<AssessmentResult>().FromSql("dbo.GetAssessmentResults #FieldA='Data1', #FieldB='Data2', #UserId = 2303");
var results2 = Set<AssessmentResult>().FromSql("dbo.GetAssessmentResults #FieldA= {0}", intData);
Both of these calls result in
"Incorrect syntax near '#FieldA'"
Any ideas?
We recently introduced the .FromSql() extension method on DbSet. It has the added benefit that you can continue composing LINQ on top of it.
var customers = db.Customers
.FromSql("SELECT * FROM Customer")
.Where(c => c.Name.StartsWith("A"));
I want to include child objects on an IQueryable list..
I want to include a child object on selected columns of some table type IQueryable list..
I tried like this:
IQueryable<Persons> persons = Context.Persons.Select(x=> new persons{Pkid=x.pkid, FirstName=x.FirstName}).AsQueryable();
persons= persons.Include("Address");
this include of child objects is not working..anyone please help...where I am doing wrong..
thanks alot...
Include doesn't work with projection. Moreover it is not needed. Just do this:
var query = context.Persons
.Select(x => new PersonDto
{
Id = x.pkid,
FirstName = x.FirstName,
Address = x.Address
});
Few points here:
No Include
Address accessed directly in projection, EF will handle this
I'm using PersonDto as target of projection. PersonDto has just Id, FirstName and Address.
You can project to custom type or anonymous type but you cannot project to entity type (the mapped type) - it doesn't work and it throws exception.
If you want to use mapped type you can't return only selected scalar columns - all columns will always be loaded. Only navigation properties can be loaded selectively. To overcome this people sometimes use Table splitting but that is something which works if you can divide your big entity into disjunct entities. In your scenario use just projection.
You cannot use Include() on a projection, try this:
Iquerable<Persons> persons = Context.Persons
.Include("Address")
.Select(x=> new persons{Pkid=x.pkid, FirstName=x.FirstName})
.AsQuerable();
Also you have a naming conflict, you project to a type persons and want to hold the results in an IQueryable named persons - one of them is wrong. Is there a reason you need the projection at all? You could just do
Iquerable<Persons> persons = Context.Persons.Include("Address");
First: Check if lazy loading is enabled or not. I experienced different results when it was enabled. I prefer lazy loading being disabled.
Second: Check this syntax:
result = (From person In context.Persons.Include("Address")).ToList();
P.S.: Useful EF Tips & Tricks : http://blogs.msdn.com/b/alexj/archive/2009/03/26/index-of-tips.aspx
UPDATE:
Include is not working, because your are using it on newly created objects, not the objects available in the context. you should use Include before creating new objects.
Check This:
result = (From person In context.Persons.Include("Address") Select New With {.FirstName = item.FirstName, .AddressValue = item.Address.Value}).ToList();
I am writing a RIA service, which is also exposed using SOAP.
One of its methods needs to read data from a very big table.
At the beginning I was doing something like:
public IQueryable<MyItem> GetMyItems()
{
return this.ObjectContext.MyItems.Where(x => x.StartDate >= start && x.EndDate <= end);
}
But then I stopped because I was worried about the performance.
As far as I understand MyItemsis fully loaded and "Where" just filters the elements that were loaded at the first access of the property MyItems. Because MyItemswill have really lots of rows, I don't think this is the right approach.
I tried to google a bit the question but no interesting results came up.
So, I was thinking I could create a new instance of the context inside the GetMyItems method and load MyItems selectively. Something like:
public IQueryable<MyItems> GetMyItems(string Username, DateTime Start, DateTime End)
{
using (MyEntities ctx = new MyEntities ())
{
var objQuery = ctx.CreateQuery<MyItems>(
"SELECT * FROM MyItems WHERE Username = #Username AND Timestamp >= #Start AND Timestamp <= #End",
new ObjectParameter("#Username", Username),
new ObjectParameter("#Start", Start),
new ObjectParameter("#End", End));
return objQuery.AsQueryable();
}
}
But I am not sure at all this is the correct way to do it.
Could you please assist me and point out the right approach to do this?
Thanks in advance,
Cheers,
Gianluca.
As far as I understand MyItemsis fully loaded and "Where" just filters the elements that were loaded at the first access of the property MyItems.
No. That's entirely wrong. Don't fix "performance problems" until you actually have them. The code you already have is likely to perform better than the code you propose replacing it with. It certainly won't behave in the way you describe. But don't take my word for it. Use the performance profiler. Use SQL Profiler. And test!