EF saving property instead of base property - c#

So i have this property in my partial class overriding the property of my POCO
public new double PaidOvertime
{
get
{
if (!InHoures)
{
return Math.Round(base.PaidOvertime/ 7, 2);
}
else
{
return base.PaidOvertime;
}
}
set
{
if (!InHoures)
{
base.PaidOvertime = value * 7;
}
else
{
base.PaidOvertime = Math.Round(value, 2);
}
statsChanged();
}
}
The thing is, when it come to saving, EF save the value of this property. I would like EF to save the value of the base property or the private variable behind the base property.
Is ther a workaround or something that im missing?
PS : when i say 'saving' i mean saving to the DB

I expect you are using some inheritance mapping otherwise it should not work at all.
Once you use new in derived class you are telling .NET that this is the implementation you want to use every time it works with your class instance. The base implementation is used only if you cast class to base type and work with it as with base type - the question is if this works with EF.
Simply don't do that. new keyword in method and property declaration is something you should use only if you have control over all code using your object. Otherwise you never know which implementation will be called. EF is not your code.

Related

Casting contents of an indexer's returned collection?

I have a table/row/column data structure setup. There is a string-based indexer in the DtaTable class to return DtaRows, and another on the DtaRow class to return DtaColumns. So you can write things like...
return theTables["tablename"]["rowidentifier"]["columnname"];
In actuality, the objects inside the tables are not DtaRows, but one of about three dozen subclasses, like InflationRow and CurrencyRow. Each table contains only objects of those types, so for instance...
theTables["Inflations"]["General"];
always returns an InflationRow.
Now to make this easier to access from C#, I have a bunch of methods at a higher level like...
public DtaTable Inflations { get {return pTables["Inflations"];} }
Now the problem I'd like to solve is that when someone calls one of these methods, they don't get an InflationRow, because DtaTable has DtaRows. So for instance...
MyInfRow = Inflations["General"];
returns a DtaRow. So I have to cast all the time...
MyInfRow = (InflationRow)Inflations["General"];
I want to get rid of all the casting.
The only solution I have found so far is to make 36 new subclasses of the table object, each overriding the indexer return type. This seems worse than the casting.
Is there some simpler way to do this?
It you know that callers are only primarily going to use another indexer, you can introduce a generic class providing that:
public class SpecializedTable<T>
{
private readonly DtaTable table;
// Just in case anyone really wants this
public DtaTable Table { get; }
public SpecializedTable(DtaTable table)
{
this.table = table;
}
public T this[string row] { get { return (T) (object) table[row]; } }
}
As an aside, these DtaTable etc names feel annoying unpronounceable / easily confusable with the .NET DataTable classes. If you're in a position to rename them, I'd suggest you do so.
Then your Inflations property can be:
public SpecializedTable<InflationRow> Inflations
{
get
{
return new SpecializedTable<InflationRow>(pTables["Inflations"]);
}
}
You may want to cache this to avoid creating a new object each time you call the property though.
At that point, this code: Inflations["General"] will perform the cast appropriately for you.
Use as instead of direct cast. If casting is valid it will return the instance, otherwise it will stay as NULL.
public MyInfRow Inflations { get {return pTables["Inflations"] as MyInfRow } }

Windows Forms data binding

So, my question is about the exact methodology behind windows form data binding.
I wrote a simple code, where i created a View, an IViewModel interface and a ViewModel.
interface IVM
{
}
and
public class Vm : IVM
{
int number;
public int Number
{
get
{
return this.number;
}
set
{
this.number = value;
}
}
}
the form looks like:
public partial class Form1 : Form
{
private IVM vm;
public Form1()
{
InitializeComponent();
this.vm = new Vm();
this.iVMBindingSource.DataSource = this.vm;
}
}
and the related designer part is:
this.textBox1.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.iVMBindingSource, "Number", true));
...
this.iVMBindingSource.DataSource = typeof(WindowsFormsApplication1.IVM);
You can clearly see that IViewModel interface does not publish a Number property, but the concrete ViewModel class has a Number property.
Although in design time i can't use the designer to bind the property (since IVM has no Number prop), i can manually write "iVMBindingSource - Number" into the textbox's Test property, to bind it.
My question is, how does binding work EXACTLY? Why don't I receive a runtime error, while trying to access IVM's not existing Number property?
(I tested and it actually changes the VM's Number prop properly)
Does it use some kind of reflection? How does this "magic" binding string works?
Thanks for your answers!
Jup it's done by reflection. I just checked the code and the binding is done by the Binding class. There is a method called CheckBindings which ensures the property you want to bind on is available. It basically works like this:
if (this.control != null && this.propertyName.Length > 0)
{
// ...certain checks...
// get PropertyDescriptorCollection (all properties)
for (int index = 0; index < descriptorCollection.Count; ++index)
{
// select the descriptor for the requested property
}
// validation
// setup binding
}
As Ike mentioned, you can find the source code here:
http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Binding.cs,3fb776d540d0e8ac
MSDN Reference: https://msdn.microsoft.com/en-us/library/system.windows.forms.binding(v=vs.110).aspx
As derape already mentioned, Binding uses reflection. It must use reflection because it cannot know anything about the class you are using. The evaluation will be done at runtime. Since your concrete type Vm got the specified property Number, reflection will return it and Binding class is satisfied. Binding is really flexible as long as the property name is valid.
On the other hand, when you are using the designer, it cannot know which concrete type you will use. Therefore it only allows you to use properties of the common base IVM. If you enter the string manually, design time evaluation will be skipped and input is passed to the binding constructor.
If you want to use designer support, just use the the concrete type or if you don't know the concrete type but need the property Number, simply create a new interface and derive from IMV.

The property has not been declared on the Type XXX Exception in Entity Framework

I have a file Unit.cs
public class Unit
{
public UnitType UnitTypeState {get;set;}
}
public enum UnitType
{
Folder = 0,
Teststeps = 1,
}
When I put the enum definition into another class like UnitDTO I got this exception:
The property 'UnitTypeState' is not a declared property on type 'Unit'. Verify that the property has not been explicitly excluded from the model by using the Ignore method or NotMappedAttribute data annotation. Make sure that it is a valid primitive property.
Well thats not truee hehe the property UnitTypeState is a declared property in the Unit class class.
How can I fix that without moving the enum back to the Unit class?
UPDATE
I have still done some research about the bug:
"The context cannot be used while the model is being created."
The odd thing is I get this exception on a entity which is the parent of the entity with the UnitTyeState property ?!
using (var context = new ITMS.DataAccess.ITMSContext())
{
return context.Templates.ToList();
}
so it seems the template entity is created then this exception is thrown? Or behaves EF like this: At the first DB access at all every entities or the whole model is created?
Nested types are currently not supported by EF - applies to both StructuralType (i.e. entity and complex types) and enum types.
Adding a link to the EF work item that is exactly about this issue: http://entityframework.codeplex.com/workitem/119
Try using the following, Perhaps the enum just needs to derive from a primitive to work?
public enum UnitType : int
{
Folder = 0,
Teststeps = 1
}

HDI: Constrain Property Set on Linq-To-Sql class

How do I constrain property setter on Linq-To-Sql class
I have a custom field that needs validation and the designer class can be over written.
I have overrider setter methods which would work but how to I restrict setting on the Linq-To-Sql class?
public partial class Frequency : INotifyPropertyChanging, INotifyPropertyChanged
{
public void SetStartTime(TimeSpan startTime)
{
if(startTime.Days > 0){throw new Exception("No day value is valid for start time value";}
this._StartTime = string.Format("{0}:hh\\:mm\\:ss", startTime);
}
public TimeSpan GetStartTime()
{
IEnumerable<int> startTime = this._StartTime.Split(':').Cast<int>();
return new TimeSpan(startTime.ElementAt<int>(0), startTime.ElementAt<int>(1), startTime.ElementAt<int>(2));
}
}
LINQ 2 SQL has everything you need to overcome this problem if you use the LINQ to SQL Classes designer.
Let's say your table has a column "Number" of type Int32.
The designer will create:
Field -> _Number
Property -> Number
Method -> OnNumberChanging(int value)
Method -> OnNumberChanged()
The last 2 methods are partial. This means you don't have to touch the designer generated files in case you refresh your classes from the database.
By creating the following in another file:
public partial class MyLinqToSqlClass
{
partial void OnNumberChanging(int value)
{
//your code here
//throw exception if necessary when validating
}
}
you get what you need.
This piece of code gets called inside the set method of the Number property right before the value of the field gets changed.
This way you don't worry about using the set method of the property.
Hope this helps.

How to pass a generic object to a Aspx page

I am working on an ASP.Net MVC website and I am stuck on a getting my C# code using generics to play nice with my views.
I have a Controller that passes a Model to a View (so far so good). The Model is of type IDescribedEnumerable<T> with some constraints on T, among those is the constraint that T inherits from an interface (IDescribedModel).
I can easily write a View that accepts an IDescribedEnumerable<Country> and that will work as long as T is in fact the type Country.
However, I'd also like to write a default view that accepts an IDescribedEnumerable of <<whatever>> and that will render it. This should be entirely possible. I don't always need to know the specific type of the Model. Often just knowing that it's an IDescribedModel is enough.
As long as I stay in C# there is no problem. When I don't care about the specific type I just declare methods and objects as accepting a <T>. When I do care I declare them as accepting Country.
But:
(1) If I want to render a View I have to pick an type. I can't just say Inherits="System.Web.Mvc.ViewUserControl<IDescribedEnumerable<T>>" I have to specify an existing type between the <>. (even if I were to inherit from ViewUserControl I'd have to cast it to an IDescribedEnumerable<<something>>.
(2) Ideally I'd say that Model is IDescribedEnumerable<IDescribedModel> in the default View and IDescribedEnumerable<Country> in the specific implementation. However, then my Controller needs to know whether he's going to render to the default View or the specific view. It is not possible to simply cast an object that is IDescribedEnumerable<Country> to IDescribedEnumerable<IDescribedModel>. (IIRC it is possible in C# 4, but I'm using 3.5)
So what should I do? All options I can think of are very sub-optimal (I'm not looking forward to removing the generics and just casting objects around, nor to copy pasting the default view 65 times and keeping the copies synchoronized, nor going reflection gallore and creating an object based on a known Type object)
while awaiting some C# genius to come along with the answer to all my problems I have implemented the trick that IEnumerable also uses:
I added a method public IDescribedEnumerable<IDescribedModel> AsIDescribedModels() to the IDescribedEnumerable interface and created a new class GenericDescribedEnumerable<T> : IDescribedEnumerable<IDescribedModel>. In my DescribedEnumerable<T> class I create a GenericDescribedEnumerable and return that. In the GenericDescribedEnumerable I return this
in full code:
public interface IDescribedModel<T> : IDescribedModel{
T original {
get;
}
}
public interface IDescribedEnumerable {
IDescribedEnumerable<IViewModel> AsIViewModels();
}
public interface IDescribedEnumerable<T> : IDescribedEnumerable
where T : IDescribedModel{
IEnumerable<T> GetViewModels();
}
public class DescribedEnumerable<T> : IDescribedEnumerable<IDescribedModel<T>>{
public DescribedEnumerable(IEnumerable<T> enumerable) {}
public IDescribedEnumerable<IViewModel> AsIViewModels() {
return new GenericDescribedEnumerable<T>(/*allProperties*/);
}
public IEnumerable<T> GetViewModels() {
foreach ( T obj in _enumerable ) {
var vm = new DescribedModel<T>( obj);
yield return vm;
}
}
}
public class GenericDescribedEnumerable<T> : IDescribedEnumerable<IViewModel>{
//pass in the constructor everything you need, or create in the
//constructor of DescribedEnumerable<T>
public GenericDescribedEnumerable(/*allProperties*/) {
}
public IEnumerable<IViewModel> GetViewModels() {
foreach ( T obj in _enumerable ) {
var vm = new PlatoViewModel<T>( obj );
yield return vm;
}
}
public IDescribedEnumerable<IViewModel> AsIViewModels() {
return this;
}
}
Yeah, that will work or use the model as object, and cast it appropriately. That's the approach the ViewPage class uses, with ViewPage and ViewPage : ViewPage.
Inherits="System.Web.Mvc.ViewUserControl<IDescribedEnumerable<T>>"
...
Model.Cast<IModel>()

Categories