My Code for a controller:
public ViewResult Index(int? ProjectID)
{
var user = HttpContext.User;
User profile = db.Users.Where(d => d.Email == user.Identity.Name).Single();
var contracts = db.Contracts.Include(c => c.Project);
if (!user.IsInRole("Admin"))
{
contracts = contracts.Where(p => p.Project.Client == profile.Client );
}
if (ProjectID != null)
{
contracts = contracts.Where(u => u.ID == ProjectID);
}
return View(contracts.ToList());
}
This is suppose to pull up all of the contracts whose parent project has the same client fk as the user currently signed in unless they are an admin. This isn't working.
I am getting the following error when the non-admin's look at the page:
Unable to create a constant value of type
'MembershipExt.Models.Client'. Only primitive types ('such as Int32,
String, and Guid') are supported in this context.
Do I need to use a second include or something?
What is the data type for p.Project.Client? I'm guessing that it is a complex type (it has properties off of it). Perhaps what you want is something like this...
contracts = contracts.Where(p => p.Project.Client.ClientID == profile.Client.ClientID );
Obviously I don't know what the object looks like, but perhaps this helps.
contracts = contracts.Where(p => p.Project.Client == profile.Client );
i am guessing the problem is in the above line the right hand side of lambda needs to be of simple type that is int32, string etc but you are having a complex type i.e. p.Project.Client
This looks wrong
db.Users.Where(d => d.Email == user.Identity.Name)
looks like you are comparing email with name
Related
A reasonably common pattern in REST APIs is to support conditional inclusion (or sometimes exclusions) of attributes in a response using a query parameter. For example:
GET /customers?include=notes
In this case, the Notes attribute is optional and won't be included in the response unless specifically requested.
The naive solution leaves a lot to be desired:
var query = dbContext.Query<Customer>();
if (include.Contains('notes'))
{
return query.Select(x => new Customer
{
Id = x.Id,
Name = x.Name,
Notes = x.Notes,
});
}
else
{
return query.Select(x => new Customer
{
Id = x.Id,
Name = x.Name
});
}
Is there a clean, elegant, DRY way to implement this feature with a combination of Entity Framework and AutoMapper in ASP.NET?
Consider the following code:
var articlesDisplay = from product in db.ProductSearchData
select product.articles;
articlesDisplay = articlesDisplay.Where(a => a[].body.Contains(searchString));
I'm trying to load a results set, but get a compiler error using the array notation in the Where clause. How should I be going about this?
The desired end result is a var articlesDisplay object that can be used in ASP.NET MVC pagination.
Thanks to any/all for your assistance!
remove the array notation
var articlesDisplay = from product in db.ProductSearchData
select product.articles;
articlesDisplay = articlesDisplay.Where(a => a.body.Contains(searchString));
A lambda expression is just like a function declaration, but instead of method name(paramters){body } it takes the form of parameters => body. So this:
a => a[].body.Contains(searchString)
Is the same as this:
bool Method(Article article)
{
return article[].body.Contains(searchString);
}
That is obviously not valid, since it won't compile. You need a Func<T,bool>, or a function that accepts a single element and returns true or false depending on whether it is to be included. So you probably want this:
bool Method(Article article)
{
return article.body.Contains(searchString);
}
Which translates to this:
a => a.body.Contains(searchString).
I'm still learning ASP.NET and I've been trying to find an answer online for my question but I couldn't find any related to what I wanted. So, my question is:
Is there a way for a Session variable to hold a record from database and then be used to access only some of the columns from it ? Kinda like this:
Session["Student"] = db.Students.Where(x => x.StudentNumber == studentNumber);
Session["Student"].SingleOrDefault().StudentId;
You're getting that error because this:
Session["Student"] = db.Students.Where(x => x.StudentNumber == studentNumber);
does not store a Student in your Session variable. It saves a query in session. Change it to Session["Student"] = db.Students.Single(x => x.StudentNumber == studentNumber); or Session["Student"] = db.Students.SingleOrDefault(x => x.StudentNumber == studentNumber);
to achieve what you're looking for.
As a side note, you should probably do some null reference checks before you try to store the object in session and also when you retrieve it before using it. More like this:
var student = db.Students.SingleOrDefault(x => x.StudentNumber == studentNumber);
if(student != null)
{
Session["Student"] = student;
}
And getting it back out:
var student = (Student)Session["Student"];
if(student != null)
{
// do something with the student
}
And finally, there is almost certainly a better way to do what you want without using session variables.
Normally I use stored procedures / work in SQL so apologies if I get the terminology slightly off here..
I have a database, with 3 seperate tables, and I need to search multiple fields in each of the 3 tables.
Im sure that I am not doing this the mose effective way, initially I am trying to do it in simple seteps to understand it.
I have the following;
var foo1 = entities.table1.Where(a => a.bodyText.Contains(searchString) || a.pageTitle.Contains(searchString));
var foo2 = entities.table2.Where(b => b.newsArticle.Contains(searchString) || b.newsArticle.Contains(searchString));
var foo3 = entities.table3.Where(c => c.ImageDescriptionContains(searchString));
I need to combine all these results into a single repeater for display.
At this point all 3 sets of data are in seperate, unique collections of anonymous data. So whats the best way of converting these into a single coherent bindable source?
I was thinking of itereating through each list in turn, pulling out the fields I need to display and putting them in a new class, then binding a lsit of these classes to the repeater.
But it all seems a bit clunky to me.
Is there a way of doing the search across all 3 tables in one go, and returning just the fields I need from each table, with a common name (i.e. in SQL I could write
select b.newsArticle as myText,
or
select newsArticle, ''
to return the news article and an empty string).
This would combine:
var foos = foo1.ToList();
foos.AddRange(foo2);
foos.AddRange(foo3);
To get just what you want:
var myExtractedValues = foos.Select(x => new {
Article = !string.IsNullOrEmpty(x.newsArticle))
? x.newsArticle
: string.Empty});
I have used an anonymous type here but you could swap the new {} with a type of your own.
I reverse the operator on the IsNullOrEmpty but that is just a personal preference (I prefer how is reads.)
To get all the results in one go you'll need to define a common class that will be used by all three queries to store the result. This class may be as well anonymous but I'll name it just for clarity.
class Data
{
public string Text{ get; set;}
}
Now, in your code you'll fetch instances of Data from database and you can use Union:
using( var entities = new YourDataContext)
{
var foo1 = entities.table1
.Where(a => a.bodyText.Contains(searchString) ||
a.pageTitle.Contains(searchString))
.Select(a => new Data{ Text = a.bodyText});
var foo2 = entities.table2
.Where(b => b.newsArticle.Contains(searchString) ||
b.newsArticle.Contains(searchString))
.Select(b => new Data{ Text = b.newsArticle});
var foo3 = entities.table3
.Where(c => c.ImageDescription.Contains(searchString))
.Select(c => new Data{ Text = c.ImageDescription});
return foo1.Union(foo2).Union(foo3);
}
I have a message table that self joins to itself where Message.ID == Message.Parent. So I have 1 Message with several ChildMessages. This is set up nicely with a Navigation property.
The code is currently:
var message = from m in soe.Messages.Include("ChildMessages")
where m.ID == id
&& m.IsActive
select m;
return message.FirstOrDefault();
What I really want is to only return 1 Message (that is equal to a particular ID and isActive) with all of its Active ChildMessages and I want to do it in one call to the database.
I have a solution for 4.0 (I'm not sure if it will work on 3.5, i hadn't check).
First, set your entities model Lazy Loading Enabled property to false. Note that as a result you will lose the references auto-loading.
Next, try this code:
var message = soe.Messages
.Where(m => (m.ID == id || m.ParentId == id) && m.IsActive)
.AsEnumerable()
.FirstOrDefault(e => e.Id == id);
The EF will resolve the parent-child references, and will not load other child references unless an explicit request will be made (like Include or Load). Notice that you must iterate over the Where results using AsEnumerable or otherwise they won't load.
I've concluded this is not possible in Entity framework.
A work around would be to return an anonymous type that satisfies the constraint. E.g.
var message = from m in soe.Messages
where m.ID == id
&& m.IsActive
select
new
{
Message = m,
ChildMessages = m.ChildMessages.Where(c => c.IsActive)
};
return message.FirstOrDefault()