Understanding the basic for Linq queries - c#

Suppose I have a Table in my database named Table1. I have 3 columns in Table1 named
FirstName
SurName
DOB
In sql I would simply do select * from Table1 and it'll display everything from that particular table. However what I am trying to understand is how would I select all the values from this table using Linq in C#. Table1 is in the database and the front-end is being developed using ASP.NET and C# I just can't seem to get my head around this. My knowledge on linq is very little so do excuse me if I'm making an obvious mistake

See below links for an intro to linq
What is Linq and what does it do?
http://weblogs.asp.net/scottgu/using-linq-to-sql-part-1
Linq provides a mean of querying data, but you still need to provide a means of Linq accessing that data - be it through Linq2Sql classes, ADO, Entity Framework, etc.
I'm a fan of Entity Framework (EF) where you set up objects that represent your data, and use a context to populate those objects.
it could look something like this:
public class Table1
{
public string FirstName { get; set; }
public string SurName { get; set; }
public DateTime DOB { get; set; }
}
public class Table1Repository
{
private readonly MyEntities _context;
public Table1Repository()
{
this._context = new MyEntities();
}
public IQueryable<Table1> Get()
{
return this._context.Table1; // in effect your "Select * from table1"
}
public IQueryable<Table1> GetById(DateTime dob)
{
return this._context.Table1.Where(w => w.DOB == dob); // pulls records with a dob matching param - using lambda here but there is also "query expression syntax" which looks more like sql
}
}
Note that you're performing linq queries on the context that represents the data, not the database itself. Linq is very powerful, but you need to provide it a means of accessing data. Even if that data is as xml, a file, a database, whatever!

In Linq2Sql you would select all field quite simply by
Starting with a datacontext:
var db = new YourDataContext()
And after that you can do things like
var myData = from row
in db.table1
select row
As you indicate yourself, your knowledge is too limited. Check out this series about L2S:
http://weblogs.asp.net/scottgu/using-linq-to-sql-part-1

Since you are using EF6 you can read your table using LinqToEntity.
public ObservableCollection<Table1> ReadTable1()
{
using (YourDBContext dc = new YourDBContext())
{
var data = (from x in dc.Table1
select x);
return new ObservableCollection<Table1>(data);
}
}

Related

Entity Framework dataset mapping

All of my DAL functions are using dbContext.Database.SqlQuery to map stored procedure results in business logic objects.
My application became more complicated and I'm looking for a modern, "up to date" way to handle the following situations. I know that I can achieve this using the low-level ADO.NET component like SqlDataReader and map the result manually, but I am sure there is the best way to do so using Entity Framework 6.
To the question: with this command dbContext.Database.SqlQuery<MyClass>, I can not handle:
The stored procedure that returns 2 result sets
Mapping the result set to a complex datatype
Example:
public class Order
{
public Customer customer { get; set; }
public Items[] items { get; set; }
}
Again, I know that I can map it manually or with AutoMapper, but I'm looking for an "up to date" approach based on Entity Framework 6.
Yes, there's a way using Translate.
Adapted from the official documentation:
var cmd = dbContext.Database.Connection.CreateCommand();
cmd.CommandText = "[dbo].[GetAllCustomersAndOrders]";
dbContext.Database.Connection.Open();
// Run the sproc
var reader = cmd.ExecuteReader();
var Customers= ((IObjectContextAdapter)dbContext)
.ObjectContext
.Translate<Customer>(reader, "Customers", MergeOption.AppendOnly);
reader.NextResult();
var Orders = ((IObjectContextAdapter)db)
.ObjectContext
.Translate<Order>(reader, "Orders", MergeOption.AppendOnly);
As far as the problem of mapping
few columns from the result to a 2nd level complex type? for example:
SELECT FirstName, LastName, OrderId FROM Orders I want to map it to:
public class Order { public Customer customer { get; set; } public int
OrderId { get; set; } }
The best would be to use a CustomerId inside your Order table, referencing a Customer table, instead of FirstName/LastName. It would be a good refactoring, normalizing the database. Otherwise you will not have a real mapping between your objects and your database, since your Order object will have a Customer property that doesn't exist in your database. In that case, you will have to create a class, e.g. NormalizedOrder
public class NormalizedOrder {
int OrderId { get; set; };
Customer OrderCustomer { get; set; };
}
And then, after the code above where you retrieve all Orders, do something like
var NormalizedOrders = Orders.Select new Order(){OrderId = e.OrderId, OrderCustomer = new Customer(){FirstName=>e.FirstName,LastName=>e.LastName}};

C# Entity Framework - What happens in the database when you fill a list with a sub query?

I have a few models that I fill in using entity framework with a MS SQL Server back end. The model consist of a record and many records that associate with that one record. I use a list to hold these records. In a LINQ Entity framework query, I write a sub query to get the list, but I don't know if I'm making a trip to the database at that moment. I may want to add on a where clause later etc.
This is the way I currently do it:
public class TestOwner
{
public Owner OwnerRecord { get; set; }
public List<OwnerUser> OwnerUsers { get; set; }
public TestOwner()
{
}
}
public static class DataTools
{
public static TestOwner testQuery()
{
//Create the holder variable for the database context.
MyEntities db = (MyEntities)CommonDataTools.GetDbContext();
//Places the database context in a using statement to have it disposed of when we are done.
using (db)
{
//Get the test owner.
return (from o in db.Owner
where o.owner_id == 44
select new TestOwner()
{
OwnerRecord = o,
OwnerUsers = (from ou in db.OwnerUser
where ou.owner_id == o.owner_id
select ou).ToList() //This is the part in question, what does this do in the database? Is this the proper way?
}).FirstOrDefault();
}
}
}
Note the query where I turn the sub query into a list.
I've been wondering if this is "better":
public class TestOwner
{
public Owner OwnerRecord { get; set; }
public IEnumerable<OwnerUser> OwnerUsers { get; set; }
public TestOwner()
{
}
}
By making in IEnumerable, I don't need the .ToList but I'm not sure if that will hurt me later on.
So for the list version, what does that do in the database? Does the query partially get run? Is this the proper way to handle this situation? If not, how is the correct way to fill a list inside of the object we are filling from the database?
First you should run the SQL profiler and see with the current code how many queries are getting generated and being sent to the database.
The Entity framework generates sql queries based on your LINQ statements. Those queries would be sent to database. Now let's consider your current code:
Part I:
return (from o in db.Owner
where o.owner_id == 44
This will return a IQueryable<> object which generated and trigger query in the DB when enumerated in loop or a aggregate function like 'count(), sum()' etc. or conversion functions like .ToList() is called.
Same will happen to your inner LINQ statement. But the difference is every time you enumerate the outer statement result the sub query will be triggered to database because you have a .ToList().
Part II:
(from ou in db.OwnerUser
where ou.owner_id == o.owner_id
select ou).ToList()
What if you remove `ToList()'? Your sql will be generated as single statement including your sub query. So enumeration will only trigger query in the DB only once. So it would reduce your round trips to DB.
Further, IEnumerable<> would be a better choice as it supports deferred execution like IQueryable<>.
For Further reading Returning IEnumerable<T> vs. IQueryable<T>

EntityFramework, How query a entries based on a non entity column?

I would like to store and query a calculated field. For instance, the fallowing table:
public class ModelTest
{
[Key]
public int Id { get; set; }
public int A { get; set; }
public int B { get { return CSharpFunction(A) ; } }
}
I want be able to query the values from the table like this.
results = db.ModelTests.Where(m => m.B = 10);
However i got the fallowing error:
The specified type member 'B' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
The only way is to query ALL entries from the db db.ModelTests.ToList() and then selects based on the Where statent later.
Is possible to store the B value into the db and optimize this kind of query ?
(other solutions are welcome too).
thanks
Actually, when you are using linq expressions from your DbContext object you are using linq-to-entities.
Check this other answer. linq to entities vs linq to objects - are they the same?

How can i return a dataReader using Entity Framework 6.1?

Exactly as the question asks. I am using entity framework for most of my code, but i also need to execute and return a count or columns from a sql table that is not within my entity framework context.
You can run a raw query using Entity Framework, for example:
using (var context = new BloggingContext())
{
var blogNames = context.Database.SqlQuery<string>(
"SELECT Name FROM dbo.Blogs").ToList();
}
If you want to return a more complex type, you can define your own class and use that instead. As long as the properties match the names of the columns you select, it will work. So lets make a class:
public class MyClass
{
public int Id { get; set; }
public string UserName { get; set; }
}
And use it:
List<MyClass> result = ctx
.Database.SqlQuery<MyClass>("SELECT Id, UserName FROM dbo.Users")
.ToList();
The whole point of an IDataReader is to Cursor through the data as it is being returned over the wire (exempli gratia TCP/IP) and thus not incur the overhead of stuffing it all into memory. If you're dealing with millions of rows, then reading everything into memory is a bad idea. If that is the case, then grab the underlying connection string from EF API and utilize ADO.NET. There's better better Aysnc support there as well.

Is there a work around for unioning two entities of the same interface using entity framework?

I have a search model class that searches different entity sets with the entity itself implementing a IAssignable interface. The code looks like this.
public void Search()
{
List<T> lessons = new List<T>();
List<T> courses = new List<T>();
if (ShowLessons)
lessons = db.Set<Lesson>()
.Where(IAssignableExtensions.SearchPredicate(q))
.Select(LessonMapping).ToList();
if (ShowCourses)
courses = db.Set<Course>()
.Where(IAssignableExtensions.SearchPredicate(q))
.Select(CourseMapping).ToList();
Results = lessons.Union(courses).ToList<T>();
}
The static extension is irrelevant, it just searched based on the query. I would prefer to bust this into it's own rather than static extension but eh. Now this works as expected. I am pulling to memory two datasets, lessons and courses, I am unioning them into a IEnumerable of a generic type based on teh Course Mapping or Lesson Mapping Expressions.
public Expression<Func<IAssignable, T>> LessonMapping { get; set; }
public Expression<Func<IAssignable, T>> CourseMapping { get; set; }
The problem is when I want to do any type of paging. As you can see the lessons and courses are searched, brought into memory and then unioned and returned. If I do any paging using an IPagedList for example, it is bringing back ALL lessons and courses then it is only using a subset of the total data in the list for the pages.
If Entity Framework supported interfaces I would just do a cast on the interface and union right at the db call. I haven't changed this code yet but I feel I might have to create a custom stored procedure or use the Query call on the datacontext, but if I use a stored procedure I have to make sure to update it on any changes to the domain, and if I use the Query I have to re-jig the selects, interfaces and still have to worry about inline sql...
Anyone have any ideas?
UPDATE
The solution that I ended up using after thinking about Erik's solution was to just use a projected object that implemented IAssignable.
public class SomeProjection : IAssignable
{
public int ID { get; set; }
public string Name { get; set; }
public string Description {get;set;}
public string Privacy {get;set;}
}
And then used it within the union call queryable
Results = db.Set<Lesson>().Select(p => new SomeProjection() { Privacy = p.Privacy, ID = p.ID, Name = p.Name, Description = p.Description })
.Union(db.Set<Course>().Select(p => new SomeProjection() { Privacy = p.Privacy, ID = p.ID, Name = p.Name, Description = p.Description }))
.Where(IAssignableExtensions.SearchPredicate(q))
.Select(Mapping).ToList<T>();
If Entity Framework supported interfaces I would just do a cast on the interface and union right at the db call.
It has nothing to do with what Entity Framework supports. If you create an interface, it is independent of the SQL technology in the back end and you want EF to somehow magically select properties based on an interface with no mappings or configuration? Not going to happen.
Instead you could simply use inheritance if there are some properties that are the same between objects, then you don't even need to union them, unless you are where-ing on properties that don't exist between both.

Categories

Resources