ok, i have to admit that until now i still do not know the best way to return multiple objects using linq to sql.
public IList<Course> GetAllStudentCourses()
{
IList<Course> output = new List<Course>();
using (lenDataContext db = new lenDataContext())
{
var result =
from ct in db.CourseByTutors
join c in db.Courses on ct.CourseId equals c.Id
join u in db.Users on ct.TutorId equals u.Id
select new
{
c,
u,
};
foreach (var r in result)
{
Course course = new Course();
course.CourseByTutor = new CourseByTutor();
course = r.c;
course.IsGroupString = (r.c.IsGroup == 1) ? "Yes" : "No";
course.User = r.u;
output.Add(course);
}
}
return output;
}
I would like to return Course and User objects back to UI.
private void InitializeData()
{
Course c = new Course();
dgCourses.AutoGenerateColumns = false;
bs.DataSource = c.GetAllStudentCourses().ToList();
dgCourses.DataSource = bs; //bs is bindingsource
}
How do i display the user data e.g. Name to the Gridview?
i have put User.Name to the datapropertyName but it still showing nothing.
my Course.User has value.
If you return db.CourseByTutors you should have access to both the users and the courses. The two inner joins you are doing above seem unessecary because you should be able to access them via EntitySet. Just use the navigation properties to access all the users and courses.
public IQueryable<CourseByTutors> GetAllStudentCourses()
{
lenDataContext db = new lenDataContext();
return db.CourseByTutors;
}
Then in your gridview you can reference the properties by Coures.property and Users.property on a databound column. You can't use a using statement though because as soon as you return the IQueryable you would dispose of the datacontext.
You can flatten your object by wrapping them in another object :
public class CourseDisplay
{
private Course course;
public CourseDisplay(Course course)
{
this.course = course;
}
public string CourseName
{
get { return course.Name; }
}
public string UserName
{
get { return course.User.Name;}
}
}
It is simpler to bind to a child property in ObjectListView.
Related
I have letter and user tables in database:
User("Id", "Name")
Letter("Id", "UserId", "Title")
and i use this code in class for get letter list:
public static mytype GetList()
{
var lst = (from l in Letters.ToList()
select new {l.Id, l.Title, l.tblUsers.Name}).ToList();
return lst;
}
please help me for choosing the right type. i want not use this code:
public static List<Letter> GetList()
{
List<Letter> lst = new List<Letter>();
lst = (from l in Letters.ToList()
select l).ToList();
return lst;
}
You need to define a type for this.
new {l.Id, l.Title, l.tblUsers.Name}
is the definition of an anonymous class. To use it as a return value, you should define a struct or class which represents the information you want to return. You can use dynamic, but it will easily lead to runtime errors when you change the returned data structure as the callers of the method will not know how the return value looks like.
For example:
struct UserLetter {
public Guid Id {get;set;}
public string Title {get;set;}
public string AuthorName {get;set;}
}
public static IList<UserLetter> GetList()
{
return (from l in Letters
select new UserLetter
{ Id = l.Id, Title = l.Title, AuthorName = l.tblUsers.Name}).ToList();
}
Try like this
class mytype
{
public int id;
public string title;
public string name;
}
public static List<mytype> GetList()
{
return (from l in Letters.ToList() select new mytype{id=l.Id,title=l.Title, name=l.tblUsers.Name}).ToList();
}
You need to apply a join with user table.
public static List<objLetter> GetList()
{
List<objLetter> lst = new List<objLetter>();
lst = from ltr in Letters
join user in Users on ltr.UserId equals user.UserId
select new objLetter {Id = ltr.Id , Title = ltr.Title, Name = user.Name })
return lst;
}
You're creating an anonymous type so either you can create a new class holding the properties you're interested in or use dynamic objects
public static IEnumerable<dynamic> GetList()
{
var lst = (from l in Letters.ToList()
select new {Id = l.Id, Title = l.Title, UserName = l.tblUsers.Name}).ToList();
return lst;
}
Then in your calling code just iterate over the dynamics objects and call the dynamic properties
foreach (var dynamicObject in GetList())
{
Console.WriteLine(dynamicObject.UserName);
}
Unless your dynamic objects have a very small scope in your application, a new class would probably be a better choice since you'll benefit from type-checks
I have a UnitOfWork/Service pattern where I populate my model using NHibernate before sending it to the view. For some reason I still get the YSOD, and I don't understand why the object collection is not already populated.
My controller method looks like this:
public ActionResult PendingRegistrations()
{
var model = new PendingRegistrationsModel();
using (var u = GetUnitOfWork())
{
model.Registrations = u.UserRegistrations.GetRegistrationsPendingAdminApproval();
}
return View(model);
}
The service/unit of work looks like this:
public partial class NHUserRegistrationRepository : IUserRegistrationRepository
{
public IEnumerable<UserRegistration> GetRegistrationsPendingAdminApproval()
{
var r =
from UserRegistration ur in _Session.Query<UserRegistration>()
where ur.Status == AccountRegistrationStatus.PendingAdminReview
select ur;
NHibernateUtil.Initialize(r);
return r;
}
}
What am I doing wrong?
The problem you are having is no different than the problem you would have with any other LINQ provider. You need to execute your query in order to get the results. If you don't have a valid context, that won't work.
This problem is easy to fix without condemning LINQ to NHibernate. Just change
public IEnumerable<UserRegistration> GetRegistrationsPendingAdminApproval()
{
var r =
from UserRegistration ur in _Session.Query<UserRegistration>()
where ur.Status == AccountRegistrationStatus.PendingAdminReview
select ur;
NHibernateUtil.Initialize(r);
return r;
}
to
public IEnumerable<UserRegistration> GetRegistrationsPendingAdminApproval()
{
var r =
from UserRegistration ur in _Session.Query<UserRegistration>()
where ur.Status == AccountRegistrationStatus.PendingAdminReview
select ur;
NHibernateUtil.Initialize(r);
return r.ToList();
}
I have a LINQ query in function, like below code:
public object RetrieveFday(DateTime _dt)
{
var fp = from f in RSC.tbl_FoodPlan join food in RSC.tbl_Food
on f.FoodID equals food.FoodID
where f.Day == _dt
select new
{
FoodName= food.Name,
Fholiday= f.HoliDay
};
return fp;
}
now I call this function in other place, I want to get result and separate them to display every one in different label, when call the function and get result I cant read property of them:
var test = RetrieveFday(dt);
how can read the property in result that into test?
Anonymous types are not meant to use as a return types, so just create a new class to hold your projection data:
public class FoodNameAndHoliday
{
public string FoodName { get; set; }
public string Fholiday { get; set; }
}
And modify your RetrieveFday function to use your class in the select:
public IEnumerable<FoodNameAndHoliday> RetrieveFday(DateTime _dt)
{
var fp = from f in RSC.tbl_FoodPlan join food in RSC.tbl_Food
on f.FoodID equals food.FoodID
where f.Day == _dt
select new FoodNameAndHoliday
{
FoodName= food.Name,
Fholiday= f.HoliDay
};
return fp;
}
And you can then use your function like:
var test = RetrieveFday(dt);
foreach(var item in test)
{
DoSomethingWith(item.FoodName);
DoSomethingWith(item.Fholiday);
}
Hi I have created a class to get values form my customer's account table, I have created a class for that. I want to inform AccountId and the Field of the table I want the result back (for example FirstName). What is the best way to achieve this? I got something like the below as my alternative but I can't make it work...
This is how I want to get the result of first name:
LabelFirstName.Text = Manage.GetAccount(2, "FirstName"); // where 2 is the id I informed and FirstName is the Column I want to retrieve from the table.
the result would be "John" for example.
This is what I have:
public class Manage
{
public Manage()
{
}
public static string GetAccount(int AccountId, string Field)
{
LinqSqlDataContext contextLoad = new LinqSqlDataContext();
var q = (from p in contextLoad.MyAccounts
where p.AccountId == AccountId
select p).Single();
string var = q.?? // ?? would be my Field string "FirstName" for example
return var;
}
}
Please help
Thanks
I suggest you return the Account object, and then retreive the property where you need it, like this :
public static Account GetAccount(int AccountId)
{
LinqSqlDataContext contextLoad = new LinqSqlDataContext();
var q = (from p in contextLoad.MyAccounts
where p.AccountId == AccountId
select p).Single();
return q;
}
public void myMethod()
{
var account = GetAccout(2);
var accountName = account.FirstName;
var accountNumber = account.Number;
// ... and so on
}
If this is realy not helpful, you can use reflection like mentioned in other posts.
Good luck.
string value = (string)q.GetType().GetProperty(Field).GetValue(q, null);
You can return the Object of the class
public static Object GetAccount(int AccountId)
{
LinqSqlDataContext contextLoad = new LinqSqlDataContext();
var q = (from p in contextLoad.MyAccounts
where p.AccountId == AccountId
select p).FirstOrDefault();
return q;
}
var Account = GetAccount(int AccountId) as Account;
LabelFirstName.Text = Account.FirstName;
LabelLastName.Text = Account.LastName;
You can get all the field from the object !! So task will be achievable from one database call
A DataReader might be useful in this situation:
var q = from p in contextLoad.MyAccounts
where p.AccountId == AccountId
select p;
using (var command = dc.GetCommand(q))
{
command.Connection.Open();
using (var reader = command.ExecuteReader())
{
// expecting one row
if(reader.Read())
{
return reader.GetString(reader.GetOrdinal(Value));
}
}
return null;
}
I have a function that (via ajax) I pass a Guid and a comma delimited string of the types of objects I would like to return . I'm having trouble building a link statement that only returns the desired types. I'm struggling with how to build the query to check if string[] relatedTypes matches rw.GetType().Name. Or perhaps there's a better way.
Here's the Model...
public abstract class WebObject : IValidatableObject
{
public WebObject()
{
this.Id = Guid.NewGuid();
RelatedTags = new List<Tag>();
RelatedWebObjects = new List<WebObject>();
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
public virtual ICollection<WebObject> RelatedWebObjects { get; set; }
public IList<Guid> RelatedWebObjectIds { get; set; }
}
And here's my function
public JsonResult GetRelatedWebObjectsByWebObject(Guid id, string relatedWebObjectTypes)
{
JsonResult result = new JsonResult();
Guid webSiteId = db.WebObjects.Find(id).WebSiteId;
string[] relatedTypes = relatedWebObjectTypes.Split(',');
var resultData = (from w in db.WebObjects
where w.Id == id
from rw in w.RelatedWebObjects
where rw.GetType().Name.Contains(relatedTypes)
select rw.Id).ToList();
result.Data = resultData;
result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return result;
}
Are you looking for something like:
var relatedTypes = new HashSet<string>(relatedWebObjectTypes);
var resultData = (from w in db.WebObjects
where w.Id == id
&& relatedTypes.SetEquals
(w.RelatedWebObjects.Select(rwo => rwo.GetType().Name))
select w.RelatedWebObjectIds).ToList();
Although I would say that it isn't good practice to use a collection of simple type names in this manner. Are you sure you couldn't use a Type[] or similar here?
It's not clear from your question what exactly do you want, but I think it's this:
from w in db.WebObjects
where w.Id == id
from rw in w.RelatedWebObjects
where relatedWebObjectTypes.Contains(rw.GetType().Name)
select rw.Id
This selects all the items from WebObjects with the correct Id (I guess there should be only one, but it does not matter to the query). And for each of them, get the RelatedWebObjects whose type's name is in relatedWebObjectTypes. And for each of those, get their Id.
You would need to refactor a bit, instead of passing in the name of the types as string, you should pass the actual type then use the linq operator for OfType(Of relatedType)
The MSDN Article gives a simple example that should have you on your way.
A little late, but here's what I ended up going with...
public JsonResult GetRelatedWebObjectsByWebObject(Guid id, string relatedWebObjectTypes)
{
JsonResult result = new JsonResult();
Guid webSiteId = db.WebObjects.Find(id).WebSiteId;
List<string> relatedTypes = new List<string>(relatedWebObjectTypes.Split(','));
var resultData = (from w in db.WebObjects
where w.Id == id
from rw in w.RelatedWebObjects
select rw).ToList();
result.Data = resultData.Where(w => relatedTypes.Contains(w.GetType().BaseType.Name) == true).Select(w => new { Id = w.Id, Type = w.GetType().BaseType.Name }).ToList();//w.Id).Select(w => w.GetType().BaseType.Name).ToList();
result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return result;
}