How to apply global filter on Entity Framework? - linq

I have a table in my model named Customers with a field IsActive. Whenever I run a query on Customers, only the active customers should be retrieved. I can include the filter in every query, but that doesn't look very. I would like to be able to override the Customers property at the Object Context lever, but I am not sure if this is possible. Any help would be very appreciated! Thanks

Although a late response, I will put it here so it can help others.
You can also set a condition for your entity in your edmx file. Select your entity and Goto Mapping Details and create a new condition.

Maybe you could declare new property and use it:
public partial class MyEntities
{
public ObjectQuery<User> ActiveCustomers
{
get
{
return Customers.Where(c => c.IsActive);
}
}
}

I don't know why this is problem for you. You can put one query inside some function:
IEnumerable<Customers> GetActiveCustomers()
{
var activeCustomers =
from cust in db.Customers
where cust.IsActive == true
select cust;
return activeCustomers;
}
And call it every time you like. You can even put active customers in some private List or even better ObservableCollection. Then you can query your result again:
var myCustomers =
from cust in GetActiveCustomers()
where cust.CustomerName == "John"
select cust;
and that's it.

All you need to do is retrieve all of the customers no matter if they are active or not and then use a
foreach(Customer c in Results)
{
if(c.IsActive)
listofactivecustomers.Add(c);
}

Related

How to show custom query result to view mvc3 Razor

I have Custom query Result as
public ActionResult Index()
{
var Query = (from E in db.SITE_MASTER.AsEnumerable()
where E.IS_PAGE == true
select new
{
E.POST_TITLE,
E.POST_TEXT
}).ToList();
return View(Query);
}
Now,
How can I make view for this result or How can I create View for this Result Query.
Thanks...
You can pass an anonymous type as a model, but please don't. It's ugly and will lead to maintenance problems.
As an alternative either use the ViewBag or create concrete type and pass that.

MVC2/LINQ Repository pattern help for a beginner

I have the following method in my repository that returns a mix of two objects from my database,
public IQueryable <ICustomersAndSitesM> CustomerAndSites
{
get
{
return from customer in customerTable
join site in customerSitesTable
on customer.Id equals site.CustomerId
select new CustomersAndSitesMix(customer, site);
}
}
This is my interface code for the ICustomerAndSitesM
interface ICustomersAndSitesM
{
IQueryable<Customer> Customers { get; }
IQueryable<CustomerSite> CustomerSites { get; }
}
Im struggling with working out how and where to define CustomersAndSitesMix, should this be a seperate class or a method in the interface? and will that need to have definttions for both the customer and customer site?
I would set CustomersAndSitesMix up as a class with all the properties from your other two tables that you need. I am not sure why you are needing this interface, but I would also change the return type of your method to List<CustomersAndSitesMix> and add a ToList() on the end of your LINQ query. Then you would return an inner join of both tables, which may be what you want or you may want to add an arguement, say CustomerID to your function so you could pass it in and get only a subset.

Linq Order By not working

The Linq query "order by" is not working and I've followed all the suggestions found on your site and other sites. Any assistance would be appreciated.
[WebGet]
public IQueryable<vw_providercharge_providers> GetChargeProviders(int submitted)
{
var results = (from p in this.CurrentDataSource.vw_providercharge_providers
where p.submitted == submitted
orderby p.fullname
select p);
return results;
}
Thanks for your input!
Yes, this is a WebGet method for a WCF data service. I get a 400 error if I don't return an IQueryable type, so I modified your suggestion a little. Unfortunately, it still seems to disregard any order-by.
[WebGet]
public IQueryable<vw_providercharge_providers> GetChargeProviders(int submitted)
{
var results = (from p in this.CurrentDataSource.vw_providercharge_providers
where p.submitted == submitted
orderby p.fullname
select p).ToArray();
results.OrderBy(p => p.patientname);
return results;
}
I notice you return an IQueryable<T> - are you calling any LINQ methods on the result before you enumerate it?
Not all LINQ methods preserve order. Most commonly, calling Distinct() after you do the ordering will destroy the order.
Since your method is a marked with a WebGet attribute, I'm assuming that you are calling this method from a Web endpoint, therefore you may need to collapse the collection prior to send it through internet.
Try:
[WebGet]
public vw_providercharge_providers[] GetChargeProviders(int submitted)
{
var results = (from p in this.CurrentDataSource.vw_providercharge_providers
where p.submitted == submitted
orderby p.fullname
select p).ToArray();
return results;
}
This way you have the guarantee that the GetChargeProviders method returns and array instead of an linq expression.
Regards,
I found the cause of the issue.
I had not set the "fullname" column as an Entity Key for the "vw_providercharge_providers" data model entity. Only the identity column was set as an Entity Key. I didn't realize that was a requirement to use it in an order by clause.
Thanks again for your input.

How do you re-use select statements with Entity Framework?

Given the following query:
var query = from item in context.Users // Users if of type TblUser
select new User() // User is the domain class model
{
ID = item.Username,
Username = item.Username
};
How can I re-use the select part of the statement in other queries? I.e.
var query = from item in context.Jobs // Jobs if of type TblJob
select new Job() // Job is the domain class model
{
ID = item.JobId,
User = ReuseAboveSelectStatement(item.User);
};
I tried just using a mapper method:
public User MapUser(TblUser item)
{
return item == null ? null : new User()
{
ID = item.UserId,
Username = item.Username
};
}
With:
var query = from item in context.Users // Users if of type TblUser
select MapUser(item);
But if I do this, then the framework throws an error such as:
LINQ to Entities does not recognize
the method 'MapUser(TblUser)' method,
and this method cannot be translated
into a store expression.
You can't use regular function calls in a query definition like that. LINQ needs expression trees, it can't analyze compiled functions and magically translate that to SQL. Read this for a more elaborate explanation
The techniques used in the cited article are incorporated in linqkit (factoring out predicates) and might be of help, though I'm not sure you can use the same technique for managing projections, which is what you seem to want.
The more fundamental question you should ask yourself here IMHO is whether you really need this extra mapping layer? It seems like you're implementing something that EF is already perfectly capable of doing for you...
Try making your MapUser method static.

Filter every call made by a DataContext when using LinQ Entities

I'm using logical delete in my system and would like to have every call made to the database filtered automatically.
Let say that I'm loading data from the database in the following way :
product.Regions
How could I filter every request made since Regions is an EntitySet<Region> and not a custom method thus not allowing me to add isDeleted = 0
So far I found AssociateWith but I'd hate to have to write a line of code for each Table -> Association of the current project...
I'm looking into either building generic lambda Expressions or.. something else?
You could create an extension method that implements your filter and use that as your convention.
public static class RegionQuery
{
public static IQueryable<Region> GetAll(this IQueryable<Region> query, bool excludeDeleted=true)
{
if (excludeDeleted)
return query.Regions.Where(r => !r.isDeleted);
return query.Regions;
}
}
So whenever you want to query for regions you can make the following call to get only the live regions still providing an opportunity to get at the deleted ones as well.
context.Regions.GetAll();
It my be a little wonky for access the Products property, but still doable. Only issue is you would have to conform to the convention. Or extend the containing class.
someProduct.Regions.GetAll();
I hope that helps. That is what I ended up settling on because I haven't been able to find a solution to this either outside of creating more indirection. Let me know if you or anyone else comes up with a solution to this one. I'm very interested.
It looks to me like you're using a relationship between your Product and Region classes. If so, then somewhere, (the .dbml file for auto-generated LINQ-to-SQL), there exists a mapping that defines the relationship:
[Table(Name = "Product")]
public partial class Product
{
...
private EntitySet<Region> _Regions;
[Association(Storage = "_Regions")]
public EntitySet<Region> Regions
{
get { return this._Regions; }
set { this._Regions.Assign(value); }
}
...
}
You could put some logic in the accessor here, for example:
public IEnumerable<Region> Regions
{
get { return this._Regions.Where(r => !r.isDeleted); }
set { this._Regions.Assign(value); }
}
This way every access through product.Regions will return your filtered Enumerable.

Resources