the member " ..." has no supported translation to SQL error - c#

im learning the ropes in LINQ and created a DB and been trying to update a table record but i keep getting the member P.roject1.ChildDBdetails.Id has no supported translation to SQL.
this is the query:
public void UpdateChildrecord()
{
using (ChildDBDataContext ChildDB = new ChildDBDataContext(Con_String))
{
IQueryable<ChildDBdetails> query =
from c in ChildDB.ChildDBdetails
where c.Id == id
select c;
ChildDBdetails updaterecord = query.FirstOrDefault();
updaterecord.Team = newteam;
ChildDB.SubmitChanges();
}
}
i'm a newbie to linq-to_sql and don't really understand why this is happening.how can i fix the error?
thanks.
TableModel:
[Table]
public class ChildDBdetails : INotifyPropertyChanged, INotifyPropertyChanging
{
[Column(IsPrimaryKey = true, IsDbGenerated = false, CanBeNull = false)]
private int id;
public int Id
{
get { return id; }
set
{
NotifyPropertyChanging("Id");
id = value;
NotifyPropertyChanged("Id");
}
}
[Column]
private string team;
public string Team
{
get { return team; }
set
{
NotifyPropertyChanging("Team");
team = value;
NotifyPropertyChanged("Team");
}
}
#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region Implementation of INotifyPropertyChanging
public event PropertyChangingEventHandler PropertyChanging;
private void NotifyPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
#endregion
}

Related

Dynamic Property Creation

Let me try and illustrate an example.
I have a database table called Grades. Here is what it looks like currently.
| Id | Grade |
1 Exceeds Standards
2 Meets Standards
3 Below Standards
Now I have code that looks like this:
var myTestingExample = db.AnotherTable.Where(x => myList.Contains(x.FirstForeignKeyId))
.GroupBy(x => new { x.SecondForeignKey.Value, x.SecondTable.Name})
.Select(
x =>
new MyViewModelClass()
{
Id = x.Key.Value,
Name = x.Key.Name,
CountName = x.Count(),
CountBelowStandards = x.Count(y => y.GradingSystemId.Value == 3),
CountMeetsStandards = x.Count(y => y.GradingSystemId.Value == 2),
CountExceedsStandards = x.Count(y => y.GradingSystemId.Value == 1)
}).ToList();
Now my concern is if the user wants to create another Grade.. then I would have to manually add another property to MyViewModelClass and then have to add another line of code to the above code to get the count.. I really would want this to be dynamic so I don't have to add properties to my view model class.
How can this be achieved?
To do what you want involves introducing inheritance. See below
public class SomeViewModel : INotifyPropertyChanged
{
private ObservableCollection<IGrade> grades;
public SomeViewModel()
{
Grades = new ObservableCollection<IGrade>()
{
new Grade(1, "BelowStandards"),
new Grade(2, "MeetsStandards"),
new Grade(3, "AboveStandards")
};
}
// Add new grade here.
public void AddGrade(string name)
{
if (Grades == null)
throw new ArgumentNullException("can't be null here");
Grades.Add(new Grade(Greads.Count + 1, name));
}
public ObservableCollection<IGrade> Grades
{
get { return grades; }
set { SetField(ref grades, value, "Grades"); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, string propertyName)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
public interface IGrade : INotifyPropertyChanged
{
int Id { get; }
string Name { get; }
}
public class Grade : IGrade
{
public Grade(int id, string name)
{
Id = id;
Name = name;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, string propertyName)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
private int id;
public int Id
{
get { return id; }
set { SetField(ref id, value, "Id"); }
}
private string name;
public string Name
{
get { return name; }
set { SetField(ref name, value, "Name"); }
}
}
Then in your XAML, you bind to the relevent Grade properties. So when the user adds a new Grade, it gets displayed. Happy days.
I have not tested this code, but it should work, or at least give you the right way to go about doing what you want.
If the user wants to change the name of a grade a run time, this should also work with the above code.

Using metadata to get a reference to the class calling a certain method

When using INotifyPropertyChanged it is possible to do something like this to get the name of the property where the method invoking the event was called.
public void RaisePropertyChanged([CallerMemberName] string prop = "")
{
if (PropertyChanged != null)
{
PropertyChanged(new object(), new PropertyChangedEventArgs(prop));
}
}
Is there some other type of attribute to use to also get a reference to the class that contains that property? I want to be able to call RaisePropertyChanged() from any property from any of my viewmodel classes. All my viewmodel classes derive from a base so I'm thinking I can do something like this.
public void RaisePropertyChanged([CallerMemberName] string prop = "", [CallerClassRef] VmBase base = null)
{
if (PropertyChanged != null)
{
PropertyChanged(base, new PropertyChangedEventArgs(prop));
}
}
The keyword to access the current class reference is called this:
public void RaisePropertyChanged([CallerMemberName] string prop = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
This will work no matter how many times you derive this class, this is always the instance this function was called on.
Try using Fody - PropertyChanged add in. It helps you to inject INotifyPropertyChanged implementation to IL code.
Source code :
[ImplementPropertyChanged]
public class Person
{
public string GivenNames { get; set; }
public string FamilyName { get; set; }
public string FullName
{
get
{
return string.Format("{0} {1}", GivenNames, FamilyName);
}
}
}
When compiled
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
string givenNames;
public string GivenNames
{
get { return givenNames; }
set
{
if (value != givenNames)
{
givenNames = value;
OnPropertyChanged("GivenNames");
OnPropertyChanged("FullName");
}
}
}
string familyName;
public string FamilyName
{
get { return familyName; }
set
{
if (value != familyName)
{
familyName = value;
OnPropertyChanged("FamilyName");
OnPropertyChanged("FullName");
}
}
}
public string FullName
{
get
{
return string.Format("{0} {1}", GivenNames, FamilyName);
}
}
public virtual void OnPropertyChanged(string propertyName)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Source code copied from : https://github.com/Fody/PropertyChanged

How to use MVVM Light With Sql Server Compact - Windows Phone 7?

I am using MVVM Light, Sql Server Compact Toolkit and windows phone 7.
I created a sql server compact 3.5 database and then used the toolkit to generate the datacontext and domain class for each table.
Looks like this
[global::System.Data.Linq.Mapping.TableAttribute(Name = "ContactGroups")]
public partial class ContactGroup : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
private int _Id;
private string _Title;
private System.DateTime _LastUpdated;
private EntitySet<GContact> _GContacts;
#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();
partial void OnIdChanging(int value);
partial void OnIdChanged();
partial void OnTitleChanging(string value);
partial void OnTitleChanged();
partial void OnLastUpdatedChanging(System.DateTime value);
partial void OnLastUpdatedChanged();
#endregion
public ContactGroup()
{
this._GContacts = new EntitySet<GContact>(new Action<GContact>(this.attach_GContacts), new Action<GContact>(this.detach_GContacts));
OnCreated();
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage = "_Id", DbType = "Int NOT NULL", IsPrimaryKey = true)]
public int Id
{
get
{
return this._Id;
}
set
{
if ((this._Id != value))
{
this.OnIdChanging(value);
this.SendPropertyChanging();
this._Id = value;
this.SendPropertyChanged("Id");
this.OnIdChanged();
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage = "_Title", DbType = "NVarChar(100) NOT NULL", CanBeNull = false)]
public string Title
{
get
{
return this._Title;
}
set
{
if ((this._Title != value))
{
this.OnTitleChanging(value);
this.SendPropertyChanging();
this._Title = value;
this.SendPropertyChanged("Title");
this.OnTitleChanged();
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage = "_LastUpdated", DbType = "DateTime NOT NULL")]
public System.DateTime LastUpdated
{
get
{
return this._LastUpdated;
}
set
{
if ((this._LastUpdated != value))
{
this.OnLastUpdatedChanging(value);
this.SendPropertyChanging();
this._LastUpdated = value;
this.SendPropertyChanged("LastUpdated");
this.OnLastUpdatedChanged();
}
}
}
[global::System.Data.Linq.Mapping.AssociationAttribute(Name = "FK_GContacts_ContactGroups", Storage = "_GContacts", ThisKey = "Id", OtherKey = "ContactGroups_Id", DeleteRule = "NO ACTION")]
public EntitySet<GContact> GContacts
{
get
{
return this._GContacts;
}
set
{
this._GContacts.Assign(value);
}
}
public event PropertyChangingEventHandler PropertyChanging;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void SendPropertyChanging()
{
if ((this.PropertyChanging != null))
{
this.PropertyChanging(this, emptyChangingEventArgs);
}
}
protected virtual void SendPropertyChanged(String propertyName)
{
if ((this.PropertyChanged != null))
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private void attach_GContacts(GContact entity)
{
this.SendPropertyChanging();
entity.ContactGroup = this;
}
private void detach_GContacts(GContact entity)
{
this.SendPropertyChanging();
entity.ContactGroup = null;
}
}
Yet when I try to make it blendable(ie make fake data so when I go into blend I can work with it better instead of looking at empty boxes) nothing shows up in blend
when I have a simple domain without it works
public class ContactGroup
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime LastUpdated { get; set; }
public List<GContacts> Contacts { get; set; }
public ContactGroup()
{
Contacts = new List<GContacts>();
}
}
Then in my viewmodel locator I would have
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IContactService, DesignContactService>();
}
else
{
SimpleIoc.Default.Register<IContactService, DesignContactService>();
}
Edit
The problem line seens to be this
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
When I remove it then blend shows the data again.

Linq-To-SQL not updating on WP7

I'm new to Windows Phone 7 development and I'm in trouble with Linq to SQL. I'm trying to update an object but it just don't work. I get the object I want to update and modify the property I want, but when I call SaveChanges, the data it's not updated on database.
I already downloaded the database using ISETool and checked that data isn't updated at all.
What's strange is the querying and inserting methods works fine, but I don't know why updating it's not.
Here's the entity and the updating method code:
[Table]
public class Entrada : INotifyPropertyChanged, INotifyPropertyChanging
{
private int _Id;
[Column]
private int _DiaId;
[Column]
private int _ProjetoId;
private EntityRef<Dia> _Dia;
private EntityRef<Projeto> _Projeto;
private DateTime _Chegada;
private DateTime? _Saida;
[Column(IsPrimaryKey = true, IsDbGenerated = true, CanBeNull = false, DbType = "INT NOT NULL Identity")]
public int Id
{
get
{
return _Id;
}
set
{
if (value != _Id)
{
NotifyPropertyChanging("Id");
_Id = value;
NotifyPropertyChanged("Id");
}
}
}
[Column(CanBeNull=false)]
public DateTime Chegada
{
get
{
return _Chegada;
}
set
{
if (value != _Chegada)
{
_Chegada = value;
NotifyPropertyChanged("Chegada");
}
}
}
[Association(Storage = "_Dia", ThisKey = "_DiaId", OtherKey="Id", IsForeignKey=true)]
public Dia Dia
{
get { return _Dia.Entity; }
set
{
NotifyPropertyChanging("Dia");
_Dia.Entity = value;
if (value != null)
{
_DiaId= value.Id;
}
NotifyPropertyChanging("Dia");
}
}
[Column(CanBeNull=true)]
public DateTime? Saida
{
get
{
return _Saida;
}
set
{
if (value != _Saida)
{
_Saida = value;
NotifyPropertyChanged("Saida");
}
}
}
[Association(Storage = "_Projeto", ThisKey = "_ProjetoId", OtherKey = "Id", IsForeignKey = true)]
public Projeto Projeto
{
get
{
return _Projeto.Entity;
}
set
{
NotifyPropertyChanging("Projeto");
_Projeto.Entity = value;
if (value != null)
{
_ProjetoId = value.Id;
}
NotifyPropertyChanging("Projeto");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangingEventHandler PropertyChanging;
private void NotifyPropertyChanged(String propertyName)
{
if (null != PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private void NotifyPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
}
//UPDATE CODE:
var query = (from e in timeSheetDB.Entradas where e.Dia.Id == this.Dia.Id && (!e.Saida.HasValue) select e);
var entrada = query.FirstOrDefault();
if (entrada != null)
{
entrada.Saida = DateTime.Now;
}
timeSheetDB.SubmitChanges();
I also checked the GetChangeSet().Updates.Count(), but it's always 0. I hope you can help me :-)
thank you guys!
It appears to be the case that you're not raising the PropertyChanging event for the Saida property; this event is important for LINQ-to-SQL, so I'd suggest updating all of your members that represent columns to raise it (in addition to the PropertyChanged event)

WPF DataGrid-DataGridCheckBoxColumn vs2010 c# .net

I am working in vs2010.
I have created a DataGrid which is bounded to
ObservableCollection List;
the Class_CMD looks like this :
public class Class_RetrieveCommand
{
public string CMD { get; set; }
public bool C_R_CMD { get; set; }
public bool S_CMD { get; set; }
public bool C_S_CMD { get; set; }
}
i have 4 delegates which i pass to another window, and this window needs to update the list during runtime. During the runtime i can see the string column of the grid updated all the time but the DataGridCheckBoxColumns are never updated.
the DataGrid -
<DataGrid Background="Transparent" x:Name="DataGrid_CMD" Width="450" MaxHeight="450" Height="Auto" ItemsSource="{Binding}" AutoGenerateColumns="True">
one of the delegates which updates the bool is -
public void UpdateC_S_CMD(string Msg)
{
foreach (Class_CMD c in List.ToArray())
{
if (c.CMD.Equals(Msg))
c.C_S_CMD = true;
}
}
I don't understand why the bool columns are not updated....
can anyone help please?
thanks.
Your class Class_RetrieveCommand needs to implement the INotifyPropertyChanged interface. Otherwise the individual rows databound to the instances of the class don't know that the underlying properties have changed. If you change it to something like this, you should see the changes reflected in your grid:
public class Class_RetrieveCommand : INotifyPropertyChanged
{
private bool _cRCmd;
private bool _cSCmd;
private string _cmd;
private bool _sCmd;
public string CMD
{
get { return _cmd; }
set
{
_cmd = value;
InvokePropertyChanged(new PropertyChangedEventArgs("CMD"));
}
}
public bool C_R_CMD
{
get { return _cRCmd; }
set
{
_cRCmd = value;
InvokePropertyChanged(new PropertyChangedEventArgs("C_R_CMD"));
}
}
public bool S_CMD
{
get { return _sCmd; }
set
{
_sCmd = value;
InvokePropertyChanged(new PropertyChangedEventArgs("S_CMD"));
}
}
public bool C_S_CMD
{
get { return _cSCmd; }
set
{
_cSCmd = value;
InvokePropertyChanged(new PropertyChangedEventArgs("C_S_CMD"));
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
public void InvokePropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, e);
}
}
}
You should implement INotifyPropertyChanged in the Class_RetrieveCommand like this:
public class Class_RetrieveCommand : INotifyPropertyChanged
{
private string _CMD;
public string CMD
{
get { return _CMD; }
set { _CMD = value; OnPropertyChanged("CMD"); }
}
... similar for the other properties
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Unfortunately you can't use auto properties anymore then (except you resort to proxygenerators).

Categories