LINQ to SQL does not support casting? - c#

If I do this:
User userOOM = new User();
userOOM.Nickname = "markzzz";
UserFacebook userFacebook = new UserFacebook();
userFacebook.first_name = "marco";
db.User.InsertOnSubmit(userOOM);
userOOM.UserFacebook.Add(userFacebook);
db.SubmitChanges();
the insert is perfect, and it works. But, if I do this:
User userOOM = new User();
userOOM.Nickname = "markzzz";
UserFacebookCatcher userCatched = new UserFacebookCatcher();
UserFacebook userFacebook = (UserFacebook)userCatched;
userFacebook.first_name = "marco";
db.User.InsertOnSubmit(userOOM);
userOOM.UserFacebook.Add(userFacebook);
db.SubmitChanges();
(so, I cast the userFacebook class) I got a Object reference not set to an instance of an object. exception. It works if I remove:
userOOM.UserFacebook.Add(userFacebook);
so the casting is the problem. UserFacebookCatcher is nothing special:
public class UserFacebookCatcher : UserFacebook
{
public UserFacebookCatcher()
{
this.first_name = "marco"
}
}
LINQ to SQL does not work if I inherit a class?

Related

LINQ to Entities parameter constructor

I've looked around for multiple solutions, but non seemed to work. I aim using a LINQ query to get data and populate an object, however; when I try to assign result to the a ReponseObj I get
Only parameterless constructors and initializers are supported in LINQ to Entities.
The constructor for ObjVO is parameterless.
public static ApiResponseObject<ObjVO> GetObjVO(int ID)
{
ApiResponseObject<ObjVO> response = new ApiResponseObject<ObjVO>();
Context ctx = new Context();
var myQuery = from cb in ctx.tblBlock
join eve in ctx.tblEvent on cb.eventID equals eve.eventID
where cb.BlockID == ID
select new ObjVO
{
Id = cb.BlockID,
Name = cb.BlockHeadline,
TotalTYProjectedSales = cb.totalTYProjectedSale.Value,
StoreTYProjectedSales = cb.storeTYProjectedSale.Value,
SiteTYProjectedSales = cb.storeTYProjectedSale.Value,
ModifiedBy = cb.LAST_UPD_USER_ID,
LastModifiedDate = cb.LAST_UPD_TS,
StoreUnitsOnHand = cb.storeUnitsOnHand.Value,
AssignedCutsCount = 0,
BlockHeadline = cb.contentBlockHeadline,
BelongsToLockedAd = false,
ProductLevel = 1,
SiteAvailability = false,
};
response.responseData = myQuery.FirstOrDefault();
}
This might be because EF cannot translate your query into a SQL statement.
See this for reference.

Accessing data members of an inherited class

So I have 4 classes: Employee (base class), PartTime : Employee, FullTime : Employee, Manager : Employee. I'm trying to access unique but can't figure out exactly how. I tried casting but that didn't work. Here's what I have so far.
Employee emp1 = new Manager();
emp1.FirstName = txtFirst.Text;
emp1.LastName = txtLast.Text;
emp1.Ssn = Convert.ToInt32(txtSSN.Text);
emp1.HireDate = Convert.ToInt32(txtHire.Text);
emp1.TaxRate = Convert.ToDecimal(txtTax.Text);
emp1.Email = txtEmail.Text;
emp1.PhoneNum = Convert.ToInt32(txtPhone);
if (emp1 is PartTime)
{
emp1.HourlyRate = txtRate.Text;
emp1.HoursWorked = txtHrs.Text;
}
if (emp1 is FullTime)
{
emp1.Salary = Convert.ToDecimal(txtSalary.Text);
emp1.VacationDays = Convert.ToDouble(txtVacation.Text);
emp1.SickDays = Convert.ToDouble(txtSick.Text);
emp1.IsTaxExempt = comboTax.SelectedIndex == 0 ? true : false;
emp1.HasInsurance = comboInsurance.SelectedIndex == 0 ? true : false;
}
if (emp1 is Manager)
{
(Manager)emp1.BonusEarned = Convert.ToDecimal(txtBonus.Text);
(Manager)emp1.Department = comboDepartment.SelectedText;
(Manager)emp1.OfficeLocation = txtOffice.Text;
}
In this example, Manager has the properties BonusEarned, Department, and OfficeLocation but Employee, FullTime, and PartTime don't.
Try this (pay attention to the parenthesis):
((Manager)emp1).BonusEarned = Convert.ToDecimal(txtBonus.Text);
((Manager)emp1).Department = comboDepartment.SelectedText;
((Manager)emp1).OfficeLocation = txtOffice.Text;
Ugh, I think that is just invalid syntax. You're doing cast in the LHS of an assignment statement... It doesn't work like that. Cast has to be on the RHS so the result can be assigned. Instead try something like this;
if (emp1 is Manager)
{
var man = (Manager)emp1
man.BonusEarned = Convert.ToDecimal(txtBonus.Text);
man.Department = comboDepartment.SelectedText;
man.OfficeLocation = txtOffice.Text;
}

Generic methods with entity framework

I have a question about using a generic method with the entity framework.
I am using this example model
Data Model
And this is the code in my webform this code to populate the object.
var user = new User();
var selectedTitles = new List<UserTitle>();
var selectedDisabilities = new List<UserDisability>();
var t = titleRepository.SearchFor(d => d.Id==1 || d.Id ==2);
foreach (var temp in t)
{
selectedTitles.Add(new UserTitle { IsPublic = true, Title = temp, User = user });
}
var ds = disabilityRepository.SearchFor(d => d.Id==1 || d.Id ==2);
foreach (var temp in ds)
{
selectedDisabilities.Add(new UserDisability { IsPublic = true, Disability = temp, User = user });
}
user.FirstName = "Johnathan";
user.LastName = "Rifkin";
user.UserTitles = selectedTitles;
user.UserDisabilities = selectedDisabilities;
userRepository.Insert(user);
As you can see when populating the “UserTitles” and “UserDisabilities” properties the code is very similar, so rather than duplicate the code I would like to create a generic method that I can use to populate both the “UserTitles” and “UserDisabilities” and any other properties that I'll need in future.
Thanks in advance

Insert data into database using LINQ

I wrote a very simple method. It saves data from class DayWeather to the database. Method checks if line with that day exist in table and update her or create a new line.
I am doing it by adding new class for LINQ and move table from Server Inspector to the constructor. It generate new class WeatherTBL.
Method itself looks like this:
public static void SaveDayWeather(DayWeather day)
{
using (DataClassesDataContext db = new DataClassesDataContext())
{
var existingDay =
(from d in db.WeatherTBL
where d.DateTime.ToString() == day.Date.ToString()
select d).SingleOrDefault<WeatherTBL>();
if (existingDay != null)
{
existingDay.Temp = day.Temp;
existingDay.WindSpeed = day.WindSpeed;
existingDay.Pressure = day.Pressure;
existingDay.Humidity = day.Humidity;
existingDay.Cloudiness = day.Cloudiness;
existingDay.TypeRecip = day.TypeRecip;
db.SubmitChanges();
}
else
{
WeatherTBL newDay = new WeatherTBL();
newDay.DateTime = day.Date;
newDay.Temp = day.Temp;
newDay.WindSpeed = day.WindSpeed;
newDay.Pressure = day.Pressure;
newDay.Humidity = day.Humidity;
newDay.Cloudiness = day.Cloudiness;
newDay.TypeRecip = day.TypeRecip;
db.WeatherTBL.InsertOnSubmit(newDay);
db.SubmitChanges();
}
}
}
When I tried to call him from UnitTest project:
[TestMethod]
public void TestDataAccess()
{
DayWeather day = new DayWeather(DateTime.Now);
DataAccessClass.SaveDayWeather(day);
}
It write, that test has passed successfully. But if look into table, it has`t chanched.
No error messages shows. Does anyone know whats the problem?
P.S. Sorry for my bad English.
UDP
Problem was in that:
"...db maybe copied to the debug or release folder at every build, overwriting your modified one". Thanks #Silvermind
I wrote simple method to save employee details into Database.
private void AddNewEmployee()
{
using (DataContext objDataContext = new DataContext())
{
Employee objEmp = new Employee();
// fields to be insert
objEmp.EmployeeName = "John";
objEmp.EmployeeAge = 21;
objEmp.EmployeeDesc = "Designer";
objEmp.EmployeeAddress = "Northampton";
objDataContext.Employees.InsertOnSubmit(objEmp);
// executes the commands to implement the changes to the database
objDataContext.SubmitChanges();
}
}
Please try with lambda expression. In your code, var existingDay is of type IQueryable
In order to insert or update, you need a variable var existingDay of WeatherTBL type.
Hence try using below..
var existingDay =
db.WeatherTBL.SingleOrDefault(d => d.DateTime.Equals(day.Date.ToString()));
if(existingDay != null)
{
//so on...
}
Hope it should work..
Linq to SQL
Detail tc = new Detail();
tc.Name = txtName.Text;
tc.Contact = "92"+txtMobile.Text;
tc.Segment = txtSegment.Text;
var datetime = DateTime.Now;
tc.Datetime = datetime;
tc.RaisedBy = Global.Username;
dc.Details.InsertOnSubmit(tc);
try
{
dc.SubmitChanges();
MessageBox.Show("Record inserted successfully!");
txtName.Text = "";
txtSegment.Text = "";
txtMobile.Text = "";
}
catch (Exception ex)
{
MessageBox.Show("Record inserted Failed!");
}

LINQ Returning a set of results

i have some code that sets user's properties like so:
us = new UserSession();
us.EmailAddr = emailAddr;
us.FullName = fullName;
us.UserROB = GetUserROB(uprUserName);
us.UserID = GetUserID(uprUserName);
us.UserActive = GetUserActive(uprUserName);
where GetUserROB, GetUserID and GetUserActive all look similar like so:
private static string GetUserActive(string userName)
{
using (Entities ctx = CommonSERT.GetContext())
{
var result = (from ur in ctx.datUserRoles
where ur.AccountName.Equals(userName, StringComparison.CurrentCultureIgnoreCase)
select new
{
Active = ur.active
}).FirstOrDefault();
if (result != null)
return result.Active;
else
return "N";
}
}
it works, but i dont think it's the right way here. how can i assign userROB, ID and Active properties all in one LINQ call? without having to have 3 separate functions to do this?
If I understand correctly I believe you can do something like:
private static void GetUserData(string userName, UserSession userSession)
{
using (Entities ctx = CommonSERT.GetContext())
{
var result = (from ur in ctx.datUserRoles
where ur.AccountName.Equals(userName, StringComparison.CurrentCultureIgnoreCase)
select new
{
UserActive = ur.active,
UserROB = ur.ROB,
UserID = ur.ID
}).FirstOrDefault();
}
if (result != null) {
userSession.UserActive = result.UserActive;
userSession.UserROB = result.UserROB;
userSession.UserID = result.UserID;
}
}
In the select new you can place as many properties as you want, this way you can get from the database several properties in a single roundtrip, and handling it later.
In the example I gave, I pass the UserSession as a parameter, in any case you already have other properites alrealdy filled from other methods.
You can create a method that accepts a UserSession object as parameter, then set all three properties in it. I changed your GetUserActive a bit here:
private static void GetUserData(string userName, UserSession user)
{
using (Entities ctx = CommonSERT.GetContext())
{
var result = (from ur in ctx.datUserRoles
where ur.AccountName.Equals(userName, StringComparison.CurrentCultureIgnoreCase)
select new
{
Active = ur.active,
ID = ur.ID,
//...select all properties from the DB
}).FirstOrDefault();
if (result != null)
user.UserActive = result.Active;
user.UserID = result.ID;
//..set all properties of "user" object
}
}
Well you might consider normalising your domain model and having a User property of type User, then your method would return all of the related user data.

Categories