Can I save my Linq Iqueriable to the DB using MVC 4 and EF 5? - asp.net-mvc

I would like to do a query on Truck table and then save the results in the Vehicles table. Is this possible and if so can you show me an example. I've been stuck on this problem for a while.
IQueryable<TruckModel> result =
from d in db.Truck
select new TruckModel()
{
Model = d.Model
Color = d.Color;
};
var record = new Vehicles();
record.Model = model.Model;
record.Color = model.Color;
db.Points.Add(record);
db.SaveChanges();
return RedirectToAction("Index");

The pitfall is here
record.Model = model.Model;
record.Color = model.Color;
I guess what you intent is
record.Model = result.Model;

Related

How do I remove the foreach from this linq code?

I'm fairly new at MVC and linq and viewmodels in particular. I managed to get a create and index views to work. The "insert" wasn't as hard as the "list".
I have this linq query:
public ActionResult Index()
{
List<BlendElVM> BEVM = new List<BlendElVM>();
var list = (from Blend in db.blends
join BlendEl in db.blendEl on Blend.ID equals BlendEl.ID
select new
{
Blend.ID, Blend.Title, Blend.TransDt, BlendEl.Comment
}).ToList();
foreach (var item in list)
{
BlendElVM o = new BlendElVM(); // ViewModel
o.Comment = item.Comment;
o.Title = item.Title;
o.TransDt = item.TransDt;
o.ID = item.ID;
BEVM.Add(o);
}
return View(BEVM);
}
What I'm not sure about is the "foreach" section. When I'm running in debug, the "list" shows up fine, but if I comment out the "foreach" I get an error - ie not expecting the model. What does the foreach do? It has to do with the database, but I don't understand the where it is using the "o" and setting the columns. I thought it would all be in one linq query. Is it possible to combine the two and eliminate the "foreach"?
var BEVM = (from blend in db.blends
join BlendEl in db.blendEl on Blend.ID equals BlendEl.ID
select new BlendELVM
{
ID = blend.ID,
Title = blend.Title,
TransDT = blend.TransDt,
comment = blendEl.Comment
}).ToList();
I believe that the foreach is needed in order to read every element in the object so in this case you have:
BlendElVM o = new BlendElVM();
So you're creating and object named " o " of the type BlendELVM and this object contains all the attributes that you declared before which are: ID, Title, TransDT, etc
When you put:
foreach (var item in list)
{
BlendElVM o = new BlendElVM(); // ViewModel
o.Comment = item.Comment;
o.Title = item.Title;
o.TransDt = item.TransDt;
o.ID = item.ID;
BEVM.Add(o);
}
You're assigning to the new object o the item that you're reading in the list and in the end adding it to the BVEM list and answering if you can combine them i will say no because at first you're declaring the query and then you're reading the items on the list and assining them to the BEVM list

Entity Framework eager loading navigation property causes error when using user-defined type

Some background
I'm wanting to bind a list of objects (my model-view) to a grid. The model-view contains fields for both an specific entity and fields from a joined entity.
I was getting an error when I would try to bind due to the dbContext being out of scope. I realized I needed to use the .Include() method in order to eager load my navigation property. However, I suspect that since I'm using Linq to Entities, that I'm now generating another error:
"Unable to cast the type 'System.Linq.IQueryable1' to type 'System.Data.Objects.ObjectQuery1'. LINQ to Entities only supports casting EDM primitive or enumeration types."
My code is shown below, any ideas of what I need to do here?
Thanks in advance!
public static List<PlanViewModel> GetPlans()
{
using (var context = new RepEntities())
{
var query = (from p in context.Plans
join r in context.RealEstateDetails on p.ReId equals r.ReId
select new PlanViewModel
{
PlanName = p.PlanName,
TargetCompletionDate = p.TargetCompletionDate,
ActualCompletionDate = p.ActualCompletionDate,
Provision = p.Provision,
StatusTypeId = p.StatusTypeId,
StatusCommon = p.StatusCommon,
Building = r.BuildingName,
City = r.City,
Country = r.Country
}).Include("StatusCommon");
return query.ToList();
}
}
You are almost there, just put Include("StatusCommon") right after context.Plans. Because you need to include StatusCommon before the iteration, this way you can set StatusCommon value for every iteration.
public static List<PlanViewModel> GetPlans()
{
using (var context = new RepEntities())
{
var query = (from p in context.Plans.Include("StatusCommon")
join r in context.RealEstateDetails on p.ReId equals r.ReId
select new PlanViewModel
{
PlanName = p.PlanName,
TargetCompletionDate = p.TargetCompletionDate,
ActualCompletionDate = p.ActualCompletionDate,
Provision = p.Provision,
StatusTypeId = p.StatusTypeId,
StatusCommon = p.StatusCommon,
Building = r.BuildingName,
City = r.City,
Country = r.Country
}).toList();
return query;
}
}

Where on a List/Table in a Query

How can I do a where in a query on a list or table ?
To explain, I have a multiselect listbox where the user can select one or many values which are passed to my action. After that, I get all this values in a list and I want to do a Where on it like that :
List<string> CondCR = new List<string>();
foreach (var testCR in SubCR)
{
CondCR.Add(testCR);
}
ViewBag.CondCR = CondCR;
var query = (from i in items
where i.Field<String>("TIMING").Contains(GetTIMING) && i.Field<String>("CD_CR").Equals(CondCR)
select new Suivi{CD_CR = i.Field<String>("CD_CR"), CD_APPLI = i.Field<String>("CD_APPLI"), CD_TRT = i.Field<String>("CD_TRT"), LB_TRT = i.Field<String>("LB_TRT"),
PERIODE = i.Field<Int64>("PERIODE"), CD_JOB = i.Field<String>("CD_JOB"), LB_JOB = i.Field<String>("LB_JOB"), CD_TYP_TRT = i.Field<String>("CD_TYP_TRT"),
CD_TRT_SSIS = i.Field<String>("CD_TRT_SSIS"), DT_DEB = i.Field<DateTime>("DT_DEB"), DT_FIN = i.Field<DateTime>("DT_FIN"), DUREE = i.Field<String>("DUREE"),
TIMING = i.Field<String>("TIMING")
}).ToList();
return View(query);
SubCR contains the value that the user select in the list box, SubCR is of type string[].
I've tried to do a where on my list CondCR but it returns nothing and I don't know if it comes from my query or from an other thing.
Have you some suggestions ?
Okay, I've find the answer, I just had to do this in my query :
where CondCR.Contains(i.Field<String>("CD_CR").Trim()) && CondAppli.Contains(i.Field<String>("CD_APPLI").Trim())

Entity Framework lazy loading issue

I am trying to create a multiple choice questionnaire that is table-driven. There is a Question that has child Choices within each question.
When I iterate the listOfQuestions, the first SQL is executed. I thought by "including" Choices that this would prevent a secondary lookup from occuring when I loop though the Choices for the current Question, but it did not.
Why?
var listOfQuestions = (from q in journeyEastContext.Questions.Include("Choices")
orderby q.QuestionId
select new
{
Question = q,
Choices = q.Choices.OrderBy(c => c.Sequence)
});
foreach (var questionGroup in listOfQuestions)
{
Question question = questionGroup.Question;
Literal paragraph = new Literal
{
Text = "<P/>"
};
this.QuestionPanel.Controls.Add(paragraph);
Label QuestionLabel = new Label
{
Text = question.Text
};
this.QuestionPanel.Controls.Add(QuestionLabel);
//var sortedChoices = from choices in question.Choices
// orderby choices.Sequence
// select choices;
foreach (Choice choice in question.Choices)
{
Literal carrageReturn = new Literal
{
Text = "<BR/>"
};
this.QuestionPanel.Controls.Add(carrageReturn);
RadioButton choiceRadioButton = new RadioButton()
{
ID = String.Format("{0},{1}", question.QuestionId, choice.ChoiceId),
Text = choice.Text,
GroupName = question.QuestionId.ToString()
};
this.QuestionPanel.Controls.Add(choiceRadioButton);
}
}
It is because of the projection being part of the query.
select new
{
Question = q,
Choices = q.Choices.OrderBy(c => c.Sequence)
});
There are a few ways to approach the solution to this, the simplest would be
var quesitonsList = (from q in journeyEastContext.Questions.Include("Choices")
orderby q.QuestionId).ToList();
var listOfQuestions = from q in questionsList
Select new
{
Question = q,
Choices = q.Choices.OrderBy(c => c.Sequence)
});
This would tell EF to execute the first query (with the Choices property eagerly loaded) and then let you run through your iteration without having extra queries fired off.
.Include and .Select do not mix because of the type of query being generated in T-SQL. Basically projections use inner select statements and eagerly loaded properties use denormalization and joins to flatten the record set.

Insert into multiple database tables using Linq, ASP.NET MVC

I have a rather simple scenario where I have two tables in which I want to add data. They are managed with primary key/foreign key. I want to add new data into TABLE A and then retrieve the Id and insert into TABLE B.
I can certainly do it with a stored procedure, but I'm looking at trying to do it using Linq.
What is the best approach ?
I can certainly get the ID and do two separate inserts but that doesn't certainly seem to be a very good way of doing things.
db.Table.InsertOnSubmit(dbObject);
db.SubmitChanges();
Int32 id = dbOject.Id;
//Rest of the code
Any way to elegantly do this?
Do you have the relationship defined between the 2 tables in the object relational designed? If so, you can have linq take care of assigning the ID property of the second table automatically.
Example...
Table A – Order
OrderId
OrderDate
Table B – Order Item
OrderItemId
OrderId
ItemId
Code (Using LINQ-to-SQL):
Order order = new Order();
Order.OrderDate = DateTime.Now();
dataContext.InsertOnSubmit(order);
OrderItem item1 = new OrderItem();
Item1.ItemId = 123;
//Note: We set the Order property, which is an Order object
// We do not set the OrderId property
// LINQ will know to use the Id that is assigned from the order above
Item1.Order = order;
dataContext.InsertOnSubmit(item1);
dataContext.SubmitChanges();
hi i insert data into three table using this code
Product_Table AddProducttbl = new Product_Table();
Product_Company Companytbl = new Product_Company();
Product_Category Categorytbl = new Product_Category();
// genrate product id's
long Productid = (from p in Accountdc.Product_Tables
select p.Product_ID ).FirstOrDefault();
if (Productid == 0)
Productid++;
else
Productid = (from lng in Accountdc.Product_Tables
select lng.Product_ID ).Max() + 1;
try
{
AddProducttbl.Product_ID = Productid;
AddProducttbl.Product_Name = Request.Form["ProductName"];
AddProducttbl.Reorder_Label = Request.Form["ReorderLevel"];
AddProducttbl.Unit = Convert.ToDecimal(Request.Form["Unit"]);
AddProducttbl.Selling_Price = Convert.ToDecimal(Request.Form["Selling_Price"]);
AddProducttbl.MRP = Convert.ToDecimal(Request.Form["MRP"]);
// Accountdc.Product_Tables.InsertOnSubmit(AddProducttbl );
// genrate category id's
long Companyid = (from c in Accountdc.Product_Companies
select c.Product_Company_ID).FirstOrDefault();
if (Companyid == 0)
Companyid++;
else
Companyid = (from Ct in Accountdc.Product_Companies
select Ct.Product_Company_ID).Max() + 1;
Companytbl.Product_Company_ID = Companyid;
Companytbl.Product_Company_Name = Request.Form["Company"];
AddProducttbl.Product_Company = Companytbl;
//Genrate Category id's
long Categoryid = (from ct in Accountdc.Product_Categories
select ct.Product_Category_ID).FirstOrDefault();
if (Categoryid == 0)
Categoryid++;
else
Categoryid = (from Ct in Accountdc.Product_Categories
select Ct.Product_Category_ID).Max() + 1;
Categorytbl.Product_Category_ID = Categoryid;
Categorytbl.Product_Category_Name = Request.Form["Category"];
AddProducttbl.Product_Category = Categorytbl;
Accountdc.Product_Tables.InsertOnSubmit(AddProducttbl);
Accountdc.SubmitChanges();
}
catch
{
ViewData["submit Error"] = "No Product Submit";
}

Resources