Select All Rows Using Entity Framework - asp.net

I'm trying to select all the rows out of a database using entity framework for manipulation before they're sent to the form
var ptx = [modelname].[tablename]();
ptx.[tablename].Select(????)
what goes in the ????

I used the entitydatasource and it provide everything I needed for what I wanted to do.
_repository.[tablename].ToList();

Entity Framework has one beautiful thing for it, like :
var users = context.Users;
This will select all rows in Table User, then you can use your .ToList() etc.
For newbies to Entity Framework, it is like :
PortalEntities context = new PortalEntities();
var users = context.Users;
This will select all rows in Table User

How about:
using (ModelName context = new ModelName())
{
var ptx = (from r in context.TableName select r);
}
ModelName is the class auto-generated by the designer, which inherits from ObjectContext.

You can use this code to select all rows :
C# :
var allStudents = [modelname].[tablename].Select(x => x).ToList();

You can simply iterate through the DbSet context.tablename
foreach(var row in context.tablename)
Console.WriteLn(row.field);
or to evaluate immediately into your own list
var allRows = context.tablename.ToList();

If it's under a async method then use ToListAsync()
public async Task<List<DocumentTypes>> GetAllDocumentTypes()
{
var documentTypes = await _context.DocumentTypes.ToListAsync();
return documentTypes;
}

Old post I know, but using Select(x => x) can be useful to split the EF Core (or even just Linq) expression up into a query builder.
This is handy for adding dynamic conditions.
For example:
public async Task<User> GetUser(Guid userId, string userGroup, bool noTracking = false)
{
IQueryable<User> queryable = _context.Users.Select(x => x);
if(!string.IsNullOrEmpty(userGroup))
queryable = queryable.Where(x => x.UserGroup == userGroup);
if(noTracking)
queryable = queryable.AsNoTracking();
return await queryable.FirstOrDefaultAsync(x => x.userId == userId);
}

Here is a few ways to do it (Just assume I'm using Dependency Injection for the DbConext)
public class Example
{
private readonly DbContext Context;
public Example(DbContext context)
{
Context = context;
}
public DbSetSampleOne[] DbSamples { get; set; }
public void ExampleMethod DoSomething()
{
// Example 1: This will select everything from the entity you want to select
DbSamples = Context.DbSetSampleOne.ToArray();
// Example 2: If you want to apply some filtering use the following example
DbSamples = Context.DbSetSampleOne.ToArray().Where(p => p.Field.Equals("some filter"))
}

You can use:
ptx.[tablename].Select( o => true)

Related

How to build where predicate in EF Core in which the property selected is dynamic

I'm struggling with expression trees and Entity Framework Core.
I have a method that returns an expression tree that I will use for filtering, something like:
public Expression<Func<E, bool>> GetWherePredicate<E>(Func<E, NpgsqlTsVector> selector, string queryText)
{
return entity => selector(entity).Matches(queryText);
}
And then I'd like to invoke this method with something like:
query = query.Where(GetWherePredicate<MyEntity>(i => i.MySearchField, "the_query"));
This produces an error, something like:
System.InvalidOperationException: The LINQ expression 'DbSet()
.Where(i => Invoke(__selector_0, i)
.Matches(__queryText_1))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
While I understand why this doesn't work, I am not sure how to solve this, but suspect it has to do with using expression trees. I thought of creating a new function that has the following signature, something like:
Expression<Func<E, bool>> GetWherePredicate<E>(MemberExpression selectorForSearchField, string queryText);
But I am not able to figure out how to take that expression and apply the Matches function.
Any help is appreciated.
Thanks,
Eric
The following is a way to answer the question, but it is not as simple as I would like. Or more correctly, my intuition tells me there is a cleaner and simpler approach.
My (not so simple) approach is the following:
Create a function that takes a MemberExpression (not a function which selects the property) that looks something like the following:
public Expression<Func<E, bool>> GetWherePredicate<E>(
MemberExpression member,
string queryText)
{
// Get the parameter from the member
var parameter = GetParameterExpression(member);
// Convert the query text into a constant expression
var queryTextExpression = Expression.Constant(queryText, typeof(string));
// Create an expression for the matches function
ftsMatchesFunction = typeof(NpgsqlFullTextSearchLinqExtensions).GetMethod("Matches",
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
null,
new[] { typeof(NpgsqlTsVector), typeof(NpgsqlTsQuery) },
null);
var matchesExpression = Expression.Call(ftsMatchesFunction, member, partialSearchExpression);
return Expression.Lambda<Func<E, bool>>(matchesExpression, parameter);
}
And then to add the predicate, I have something like:
var predicate = PredicateBuilder.New<MyEntity>(false);
var myEntity= Expression.Parameter(typeof(MyEntity), "e");
var childEntity= Expression.PropertyOrField(myEntity, nameof(Invoice.Child));
var searchProperty = Expression.PropertyOrField(childEntity, nameof(Child.FtsSearchVector));
predicate = predicate.Or(_context.GetWherePredicate<MyEntity>(
searchProperty,
"the_query_text"));
And finally to add the filter to the query:
query = query.Where(predicate);
The cleaner or simpler solution is one in which does not need Expression Trees, as the only reason expression trees are needed is because I am not able to figure out how to select the search property in a way that ef can understand.
how to use the predicate to create an expression for retrieving objects from a list.
Method 1
Use the Predicate<generic> type and IEnumerable
[Fact]
public async Task TestPredicate()
{
List<Product> products = new List<Product>
{
new Product {ProductID=1,Name="Kayak",Category="Watersports",Price=275m},
new Product {ProductID=2,Name="Lifejacket", Category="Watersports",Price=48.95m},
new Product {ProductID=3,Name="Soccer Ball", Category="Soccer",Price=19.50m},
new Product {ProductID=4,Name="Corner Flag", Category="Soccer",Price=34.95m}
};
Predicate<Product> predicate = x => x.ProductID==4;
var query=Enumerable.FirstOrDefault(products,x=>predicate(x));
if (query != null) {
output.WriteLine(query.Name);
Assert.True(true);
}
}
Method 2
use Expression<Func pattern for your predicate:
Expression<Func<TimeAndAttendancePunchIn, bool>> predicate = e => e.EmployeeId == employeeId;
PageListViewContainer<TimeAndAttendancePunchInView> container = await taMod.TimeAndAttendance.Query().GetViewsByPage(predicate, order, pageSize, pageNumber);
public async Task<PageListViewContainer<TimeAndAttendancePunchInView>> GetViewsByPage(Expression<Func<TimeAndAttendancePunchIn, bool>> predicate, Expression<Func<TimeAndAttendancePunchIn, object>> order, int pageSize, int pageNumber)
{
var query = _unitOfWork.timeAndAttendanceRepository.GetEntitiesByExpression(predicate);
query = query.OrderByDescending(order).Select(e => e);
IPagedList<TimeAndAttendancePunchIn> list = await query.ToPagedListAsync(pageNumber, pageSize);
repository
public IQueryable<TimeAndAttendancePunchIn> GetEntitiesByExpression(Expression<Func<TimeAndAttendancePunchIn, bool>> predicate)
{
var result = _dbContext.Set<TimeAndAttendancePunchIn>().Where(predicate);
return result;
}

Asp Core, How to use PagingList<T>.CreateAsync() with a viewModel?

I am working on a asp.net core 1.1 project and i want to create paging in my some views. I studied microsoft documents about paging in asp core but it is very simple mode with 1 table. In my view i use multi table and use a viewmodel to initialize it. I want to use PagingList<T>.CreateAsync() method to create paging but get error:
can not convert from system.linq.Iqueryable<> to system.linq.IorderedQueryable<>
my action:
[HttpGet]
public async Task<IActionResult> Index(int? page)
{
List<BookListViewModel> model = new List<BookListViewModel>();
var query = (from b in _context.books
join a in _context.authors on b.AuthorID equals a.AuthorId
join bg in _context.bookgroups on b.BookGroupID equals bg.BookGroupId
select new
{
b.BookId,
b.BookName,
b.BookPageCount,
b.BookImage,
b.AuthorID,
b.BookGroupID,
a.AuthorName,
bg.BookGroupName
});
foreach (var item in query)
{
BookListViewModel objmodel = new BookListViewModel();
objmodel.BookId = item.BookId;
objmodel.BookName = item.BookName;
objmodel.BookImage = item.BookImage;
objmodel.BookPageCount = item.BookPageCount;
objmodel.AuthorId = item.AuthorID;
objmodel.BookGroupId = item.BookGroupID;
objmodel.AuthorName = item.AuthorName;
objmodel.BookGroupName = item.BookGroupName;
model.Add(objmodel);
}
ViewBag.RootPath = "/upload/thumbnailimage/";
int pageSize = 3;
int pageNumber = (page ?? 1);
return View(await PagingList<BookListViewModel>.CreateAsync(model.AsQueryable() , pageNumber, pageSize));
}
I have not yet written anything about paging in index view and it is a simple list of viewmodel
Well can't really be sure from the code you posted. But the exception says the the CreateAsync method needs IOrderedQueryable, but you're giving it an IQueryable.
Try changing it to pass in the query object (which I guess should implement the IOrderedQueryable, if you're using Entity framework).
The idea behind the PagingList (presumably) is to use it to do the paging in the database.
What you're doing is bringing the filterted set into memory (when for-eaching through the result), and then doing doing the paging.
The code might look something like this:
[HttpGet]
public async Task<IActionResult> Index(int page = 1)
{
var query = (from b in _context.books
join a in _context.authors on b.AuthorID equals a.AuthorId
join bg in _context.bookgroups on b.BookGroupID equals bg.BookGroupId
select new BookListViewModel()
{
BookId = b.BookId,
BookName = b.BookName,
BookPageCount = b.BookPageCount,
BookImage = b.BookImage,
AuthorId = b.AuthorID,
BookGroupId = b.BookGroupID,
AuthorName = a.AuthorName,
BookGroupName = bg.BookGroupName
}).AsNoTracking().OrderBy(u => u.BookId);
ViewBag.RootPath = "/upload/thumbnailimage/";
var pagedResult = await PagingList<BookListViewModel>.CreateAsync(query, 10, page);
return View(pagedResult);
}
Hope it helps.

Import two or multiple class models to a single controller on ASP.NET

I'm very new to ASP.NET, but I know a little programming in Java. I want to use a ZIP code to query a database which will return a string, then use that string to query another database. I wanted to do this on the same control model. I thought it would be easy, and it sounds pretty easy.
When I created the controller, I put the model class of the first database, and, so far, I've gotten as far as querying the first database, but now that I have the string I want to query a second database through the DBEntities.
This displays an error saying:
> The model item passed into the dictionary is of type
> 'System.Collections.Generic.List`1[FinalBallot.Models.AgainCandidate]',
> but this dictionary requires a model item of type
> 'System.Collections.Generic.IEnumerable`1[FinalBallot.Models.ZipTable]'.
Is there a way to solve this in an easy way?
public class Default1Controller : Controller
{
private CandidatesDBEntities db = new CandidatesDBEntities();
public string districString = "";
//
// GET: /Default1/
public ViewResult Index(string searchString)
{
var queryZip = from s in db.ZipTables select s;
var queryCandidates = from s1 in db.AgainCandidates select s1;
double sT = 0;
//method so it doesnt display the whole db
if (String.IsNullOrEmpty(searchString))
{
queryZip = queryZip.Where(s => s.ZipL.Equals(0));
}
if (!String.IsNullOrEmpty(searchString))
{
sT = double.Parse(searchString);
queryZip = queryZip.Where(s => s.ZipL.Equals(sT));
try
{
districString = queryZip.ToList().ElementAt(0).District;
}
catch
{
}
if (!String.IsNullOrEmpty(districString))
{
queryCandidates = queryCandidates.Where(s1 => s1.District.Equals(districString));
}
}
return View(queryCandidates.ToList());
}
In your view, did you specify the model to be IEnumerable<ZipTable>? The model that you're passing to your view is IEnumerable<AgainCandidate>, so you would get an error if you specified your model as something else. You'd need to change the model in your view to be IEnumerable<AgainCandidate>.
UPDATE:
Based on your revised explanation, you can do a couple things:
1) create a "ViewModel" that has two properties for each of your collections you want to display on the page like so:
public class MyViewModel
{
IEnumerable<ZipTable> Zips { get; set; }
IEnumerable<AgainCandidate> Candidates { get; set; }
}
Instantiate that in your action method and return that as your model. This would be my preferred approach.
2) Stash your two collections in the ViewData bag in your action method:
ViewData["Zips"] = queryZip.ToList();
ViewData["Candidates"] = queryCandidates.ToList();
return View(ViewData);
You can pull this data in your view like this:
#foreach (var zip in ViewData["Zips"] as IEnumerable<ZipTable>)
{
...
}

MVC3 C#4.0 / Passing variables between views

new to C# and MVC. What I would like to achieve is passing a variable as ViewData from one view to another view without using ID in the ActionResult because this view generates it own variable. I am sure there are better ways to do that, but here what I thought might work.
First I made a model:
public class EventToShow
{
public Int64? ID { get; set; }
public Int64? EventID { get; set; }
}
Then I passed the variable EventID from the first View (Telerik MVC GRID) using the following:
columns.Template(item => Html.Raw(string.Format("{1}", Url.Action("tableread", "Home", new { id = (long)item.Event_ID }), "EventID"))).Width(20);
It worked using the following in my controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult tableread1(long? id)
{
ViewData["EID"] = id;
EventToShow ctx = new EventToShow();
ctx.ID = 1;
ctx.EventID = (long)ViewData["EID"];
return RedirectToAction("EditServerSide");
}
To pass the variable to the other view I tried to use the following (I think it is very wrong):
public ActionResult EditServerSide()
{
EventToShow ctx = new EventToShow();
var model1 = ctx.(x => x.ID == 1); **// The error here is (Identifier** expected)
ViewData["EID"] = ctx.EventID;
var model = from o in new Main().OffLinePayments
select new EditOffLinePayment
{
ID = o.ID,
Amount = o.Amount,
Details = o.Details
};
return View(model, ViewData["EID"]) **(this must be wrong)**
}
I thought maybe I should make the variable like this:
private string GetFullName()
{
EventToShow ctx = new EventToShow();
var name = EventToShow().Where(x => x.ID == 1);
ViewData["EID"] = ctx.EventID;
return name;
}
First I got an error: ‘GridEdit_OfflinePayment.Models.EventToShow' is a 'type' but is used like a 'variable'
I also did not know how to incorporate returned [name] in the EditServerSide Action.
My question, is there a better way to achieve what I am trying to do, and if this approach is correct, I would appreciate any help to fix these errors
From what I understand of the question is that you would like to pass data between several Actions? Like some sort of wizard steps process where you can pass data between multiple Actions?
If that's the case then here are some related questions and their answers:
How do I pass data across ActionResults in MVC 3?
multi-step registration process issues in asp.net mvc (splitted viewmodels, single model)

Question about using Anonymous List Types

private List<T> GetFieldList()
{
var Fields = new { DisplayName = "MCP", FieldName = "t.MCP", FieldType = 1 };
var FieldList = (new[] { Fields }).ToList();
return FieldList;
}
Should I be able to do something like this?
If I understand correctly your tag "asp.net" this construction will be used as part of data binding.
Just use non generic :
private IList GetFieldList()
{
var Fields = new { DisplayName = "MCP", FieldName = "t.MCP", FieldType = 1 };
IList FieldList = (new[] { Fields }).ToList();
return FieldList;
}
It would be nice handled by all data-bound controls.
I just realized I don't need to use an anonymous list as I know the structure of the data I'm expecting, so I'll just create a small class for it.

Resources