I'm working on a MVC .NET application using EF.
I have a JqGrid in my view which works correctly bringing data from one table, but the information that I need is in two databases and three tables (Database is not normalized correctly, it sucks). I already have my two context (edmx) created in my project, I just had no idea on how to proceed in my Model. Here is my query which works fine in SQL Server
SELECT
a.idPlanta, a.idArticulo, b.DescripcionCorta, c.Planta,
a.FechaAlta, a.Existencia
FROM
CAT_ArticulosEnPlanta AS a
INNER JOIN
CAT_Articulos AS b ON a.idArticulo = b.idArticulo
INNER JOIN
[LEC].[dbo].[Plantas] AS c ON a.idPlanta = c.PlantaID
ORDER BY
b.DescripcionCorta ASC;
and here is my model that brings information from one table
public List<ArticulosPlantaView> GetArticulosEnPlanta()
{
List<ArticulosPlantaView> articuloss = new List<ArticulosPlantaView>();
using (TemakaSoftTestEntities TSTE = new TemakaSoftTestEntities())
{
ArticulosPlantaView APV;
foreach (CAT_ArticulosEnPlanta a in TSTE.CAT_ArticulosEnPlanta)
{
APV = new ArticulosPlantaView();
APV.idArticulo = a.idArticulo;
APV.idPlanta = a.idPlanta;
APV.idUsuarioAlta = a.idUsuarioAlta;
APV.FechaAlta = a.FechaAlta;
APV.Existencia = a.Existencia;
APV.Comentarios = a.Comentarios;
APV.idUsuarioElimina = a.idUsuarioElimina;
APV.FechaEliminacion = a.FechaEliminacion;
APV.Visible = a.Visible;
articuloss.Add(APV);
}
return articuloss;
}
}
public ArticulosPlantaDataView GetArticulosPlantaDataView()
{
ArticulosPlantaDataView APDV = new ArticulosPlantaDataView();
List<ArticulosPlantaView> articuloss = GetArticulosEnPlanta();
APDV.articulos = articuloss;
return APDV;
}
An example will help a lot.
THANK YOU VERY MUCH!!!
Related
I am using a database-first approach with Entity Framework in .NET Core which ends up using this. Some tables are with a relationship in SQL Server which results joined in code.
I was about to get a DateTime on a joined table and want to give a string format, but to do it I should execute first the query so I could give a format to it like what was mentioned here. The question is, why did the joined table go null after the execution?
To explain my problem easily here's the code:
var a = (from p in db.Product
select s).ToList();
var b = (from p in a
select p.Brand.DateCreated.ToString("MMMM dd, yyyy")).ToList();
// Brand contains null after execution in "a"
var c = (from p in db.Product
select p.Brand.DateCreated.ToString("MMMM dd, yyyy")).ToList();
// Brand contains data but execution gives error due to DateTime.ToString()
In the meantime, This is my solution but I need to create another Model. Which will end up a lot of Model just for this case.
public class ProductBrand
{
public class Product { get; set; }
public class Brand { get; set; }
}
var a = (from s in db.Product
select new ProductBrand {
Product = s,
Brand = s.Brand,
}).ToList().Select(s => s.Brand.DateCreated.ToString("MMMM dd, yyyy")).ToList();
EDITTED:
Above problem was solved by just updating my Model. But problem related to above question still encounter. When saving new Product the Brand becomes null after saving
To explain my problem easily here's the code:
var p = new Product { Name = "temp", BrandId = 1 };
db.Product.Add(p);
db.SaveChanged();
return p.Brand.DateCreated.ToString("MMMM dd, yyyy"); // but Brand is null
In the meantime
var p = new Product { Name = "temp", BrandId = 1 };
db.Product.Add(p);
db.SaveChanged();
if(p.Brand == null) { // Here's my temporary solution, but how about for those tables with lot of joins
p.Brand = db.Brand.FirstOrDefault(s => s.Id == p.BrandId);
}
return p.Brand.DateCreated.ToString("MMMM dd, yyyy");
Did I miss something?
Hi all the below solution works in that it creates a record in the MeetingRoomRequest table and also adds the associated amenities to that request into the MeetingRoomRequestAmenityLink table. However it just feels a bit clunky, so I was wondering if there is a nicer solution out there (i.e. not having to create 2 context instances) using MVC 3 and Entity Framework??
Please note i've set up the necessary relationships (one to many) in SQL Server and Entity Framework.
Also please note AmenityList is an array of id's (e.g. [1,2,4])
private readonly IDataRepository<MeetingRoomRequest> _meetingRoomRequestRepository = new DataRepository<MeetingRoomRequest>();
private readonly IDataRepository<MeetingRoomRequestAmenityLink> _meetingRoomRequestAmenityLinkRepository = new DataRepository<MeetingRoomRequestAmenityLink>();
var meetingRoomRequestToAdd = new MeetingRoomRequest
{
User = meetingRoomRequestViewModel.User,
UserEmail = meetingRoomRequestViewModel.UserEmail,
Title = meetingRoomRequestViewModel.Title,
Comments = meetingRoomRequestViewModel.Comments,
StartDateTime = meetingRoomRequestViewModel.StartTime,
EndDateTime = meetingRoomRequestViewModel.EndTime,
RequestStatusID = (int)Enums.RequestStatus.New,
AttendeeCount = meetingRoomRequestViewModel.AttendeeCount,
AttendeeType = meetingRoomRequestViewModel.AttendeeType,
OfficeID = meetingRoomRequestViewModel.OfficeId,
LocationID = meetingRoomRequestViewModel.LocationId,
};
_meetingRoomRequestRepository.Add(meetingRoomRequestToAdd);
_meetingRoomRequestRepository.SaveChanges();
var meetingRoomRequestAdded = meetingRoomRequestToAdd;
foreach (var item in meetingRoomRequestViewModel.AmenityList)
{
var meetingRoomRequestAmenityLinkToAdd = new MeetingRoomRequestAmenityLink
{
AmenityID = item,
MeetingRoomRequestID = meetingRoomRequestAdded.MeetingRoomRequestID
};
_meetingRoomRequestAmenityLinkRepository.Add(meetingRoomRequestAmenityLinkToAdd);
_meetingRoomRequestAmenityLinkRepository.SaveChanges();
}
The way you are going about it looks right, but there are some improvements that could be made in efficiency of processing the request.
Since these are a child/parent relationship, you can create the parent entity and then attached the childern in the foreach loop before you call save changes on the parent entity. EF will automatically populate the foreign key value on the child object with the primary (or associated key) from the parent.
You can continue to use your Entity without having to save it back out to a variable. EF's object tracking will continue to track this throughout your function.
By moving the savechanges outside of the foreach loop, you are reducing the number of calls. I believe the same amount of SQL will be sent on the one final call, but you may see increases of not having the connection open/close. There may be other built in efficiencies as well from EF
The Code
var meetingRoomRequestToAdd = new MeetingRoomRequest
{
User = meetingRoomRequestViewModel.User,
UserEmail = meetingRoomRequestViewModel.UserEmail,
Title = meetingRoomRequestViewModel.Title,
Comments = meetingRoomRequestViewModel.Comments,
StartDateTime = meetingRoomRequestViewModel.StartTime,
EndDateTime = meetingRoomRequestViewModel.EndTime,
RequestStatusID = (int)Enums.RequestStatus.New,
AttendeeCount = meetingRoomRequestViewModel.AttendeeCount,
AttendeeType = meetingRoomRequestViewModel.AttendeeType,
OfficeID = meetingRoomRequestViewModel.OfficeId,
LocationID = meetingRoomRequestViewModel.LocationId,
};
_meetingRoomRequestRepository.Add(meetingRoomRequestToAdd);
foreach (var item in meetingRoomRequestViewModel.AmenityList)
{
meetingRoomRequestToAdd.MeetingRoomRequestAmenityLinks.Add(new MeetingRoomRequestAmenityLink
{
AmenityID = item
});
}
_meetingRoomRequestRepository.SaveChanges();
I have created an ADO.NET entity data model, and using linq to update/edit my oracle database.
using (Entities ent = new Entities())
{
RUSHPRIORITYRATE rp = new RUSHPRIORITYRATE();
rp.RATE = rate;
var query = from j in ent.RUSHPRIORITYRATEs
select j;
List<RUSHPRIORITYRATE> list = query.ToList();
if (list.Count == 0)
{
ent.AddToRUSHPRIORITYRATEs(rp);
ent.SaveChanges();
}
else
{
foreach (RUSHPRIORITYRATE r in query)
{
r.RATE = rp.RATE;
}
ent.SaveChanges();
}
}
I have a method that either adds or updates a Table that will always have one record. The record's value is then only update once there is one record in place. Adding to the table is no problem, but I've looked up how to update recores through MSDN, and "ent" does not seem to have the "submitchanges" method that the solution requires. Running this, I get the error: "The property 'RATE' is part of the object's key information and cannot be modified."
As you can tell from my code, I'm absolute a beginner. After searching through other similar issues on LINQ to SQL problems, I find myself still seemingly stuck on two objectives. 1) Adding a new entry with input from the user selection from three comboboxes and a datepicker and 2) Updating an existing database entry using interactions from the datagridview.
My windows form datagridview is displaying the following output
**select b.Date, a.EmployeeName,
c.ProjectName, b.Hours
from dbo.Employees a
left outer join dbo.EmployeeProjectHours b
on a.EmployeeId = b.EmployeeId
left outer join dbo.Projects c
on b.ProjectId = c.ProjectId**
Here is my ADD method the user is providing me with ProjectName, EmployeeName, Date and Hours. Any thoughts for a layman would be appreciated.
I don't get an error running the insert, but nothing is added to my dab as well
using (ProjectHoursDataContext dbInsert = new ProjectHoursDataContext())
{
this.Validate();
EmployeeProjectHour empHours = new EmployeeProjectHour();
empHours.Date = dateDateTimePicker.Value;
empHours.Hours = Convert.ToDecimal(hoursComboBox.Text);
empHours.ProjectId = dbInsert.Projects.First(p => p.ProjectName == projectNameComboBox.Text).ProjectId;
empHours.EmployeeId = dbInsert.Employees.First(m => m.EmployeeName == employeeNameComboBox.Text).EmployeeId;
db.EmployeeProjectHours.InsertOnSubmit(empHours);
dbInsert.SubmitChanges();
}
Here is my Update attempting to use updates directly from the datagridview. I get the following error: A first chance exception of type 'System.ArgumentException' occurred in System.Windows.Forms.dll
using (ProjectHoursDataContext dbUpdate = new ProjectHoursDataContext())
{
this.Validate();
dataGridView1.AutoGenerateColumns = true;
projectBindingSource.DataSource = dbUpdate;
projectBindingSource.DataMember = "Updates";
projectBindingSource.EndEdit();
dbUpdate.SubmitChanges();
}
My best guess so far is, you want to edit and change existing Employee, Project and EmployeeProjectHours records.
So you would do:
using (ProjectHoursDataContext dbInsert = new ProjectHoursDataContext())
{
this.Validate();
// Get the records
Employee emp = new Employee();
Project proj = new Project();
EmployeeProjectHour empHours = new EmployeeProjectHour();
// Set new values to Employees tables
emp = dbInsert.Employees
.First(m => m.EmployeeName == employeeNameComboBox.Text);
//just get the empployee
//setting values will update it
emp.EmployeeName = employeeNameComboBox.Text;
// GET an existing project
proj = dbInsert.Projects
.First(p => p.ProjectName == projectNameComboBox.Text);
//update its values.
proj.ProjectName = projectNameComboBox.Text;
proj.ProjectDescription = "Test";
//GET an empHours
empHours = dbInsert.Projects.First(p => p.EmployeeId == emp.EmployeeId &&
p.ProjectId == proj.ProjectId);
//set its values
empHours.Date = dateDateTimePicker.Value;
empHours.Hours = Convert.ToDecimal(hoursComboBox.Text);
dbInsert.SubmitChanges();
}
Aside from the new code below, I also set my increment status for my projects database to NO. I had set it yes from a previous stackoverflow discussion. Thanks
public void AddInfo()
{
db.Connection.Open();
this.Validate();
EmployeeProjectHour empHours = new EmployeeProjectHour();
empHours.Date = dateDateTimePicker.Value;
empHours.Hours = Convert.ToDecimal(hoursComboBox.Text);
empHours.ProjectId = db.Projects.First(p => p.ProjectName == projectNameComboBox.Text).ProjectId;
empHours.EmployeeId = db.Employees.First(m => m.EmployeeName == employeeNameComboBox.Text).EmployeeId;
db.EmployeeProjectHours.InsertOnSubmit(empHours);
db.SubmitChanges();
db.Connection.Close();
}
I want to remove some special characters in a table of database. I've used strong typed table to do it. When i got all data into dataset from database and modified it then i called method update() of data adapter to turn dataset to database but it doesn't work.
Below is my code
DsTel tel = new DsTel();
DsTelTableAdapters.telephone_bkTableAdapter adapter = new DsTelTableAdapters.telephone_bkTableAdapter();
adapter.Connection = new SqlConnection(ConfigurationManager.AppSettings["SiteSqlServer"].ToString());
adapter.Fill(tel.telephone_bk);
foreach (DsTel.telephone_bkRow row in tel.telephone_bk.Rows)
{
row.telephoneNo = RemoveWhiteSpace(row.telephoneNo.ToString());
row.AcceptChanges();
}
tel.AcceptChanges();
adapter.Update(tel.telephone_bk);
Please give me some ideas?
Thanks in advance.
I've found the solution for this problem by using the TableAdapterManager.
Below is my code:
DsTel tel = new DsTel();
DsTelTableAdapters.telephone_bkTableAdapter adapter = new DsTelTableAdapters.telephone_bkTableAdapter();
adapter.Connection = new SqlConnection(ConfigurationManager.AppSettings["SiteSqlServer"].ToString());
adapter.Fill(tel.telephone_bk);
foreach (DsTel.telephone_bkRow row in tel.telephone_bk.Rows)
{
if (!row.IstelephoneNoNull())
{
row.telephoneNo = RemoveWhiteSpace(row.telephoneNo.ToString());
}
}
DsTelTableAdapters.TableAdapterManager mrg = new DsTelTableAdapters.TableAdapterManager();
mrg.telephone_bkTableAdapter = adapter;
mrg.BackupDataSetBeforeUpdate = true;
mrg.UpdateAll((DsTel)tel.GetChanges());
You've called AcceptChanges before the update. This means the dataset has no changes any more so there is nothing to send to the database.
Remove all of the calls to AcceptChanges and add one AFTER the update. ie:
DsTel tel = new DsTel();
DsTelTableAdapters.telephone_bkTableAdapter adapter = new DsTelTableAdapters.telephone_bkTableAdapter();
adapter.Connection = new SqlConnection(ConfigurationManager.AppSettings["SiteSqlServer"].ToString());
adapter.Fill(tel.telephone_bk);
foreach (DsTel.telephone_bkRow row in tel.telephone_bk.Rows)
{
row.telephoneNo = RemoveWhiteSpace(row.telephoneNo.ToString());
}
adapter.Update(tel.telephone_bk);
tel.telephone_bk.AcceptChanges();