I'm moving from mainly classic asp to .NET. So this may be a stupid question, but I can't find an answer.
I have an MVC App using Database First and Entity Framework. Now I would like to add some logic to the auto generated 'partial' classes. From what I have read it should be a matter of creating a new partial class with the same namespace and name. But when I do that I get an error "(This member is defined more than once)" and "Ambiguity between [partial class] and [partial class]". I understand what the error is saying, but I'm not sure how to resolve the problem.
I would like to add some logic to the set; accessor.
So in the generated class I have
public partial class QualityChecks
{
.....
public int DailyCount { get; set; }
...
}
in my new partial class I would like to add to the set code to make sure only values greater then 0 are added. If a negative value is added it needs to be logged and changed to 0
e.g. my new partial class is:
public partial class QualityChecks {
public int DailyCount {
set
{
DailyCount = value;
if it's < 0 log and set to 0
}
}
If that's not clear maybe this will help:
Currently I have loads of code that simply does
QualityChecks qc = new QualityChecks();
qc.DailyCount = enteredAmount;
....
db.QualityChecks.add(qc);
Rather then update that logic everywhere it would be nice to have it wrapped up in the QualityChecks class.
Is this the right way of going about it? If so what do I need to change to make this work?
Thank you in advance for any tips and help!
You cannot define the same members in two different files.
You can try to define a new wrapper property (eg. MyDailyCount) that add that extra logic and update the underlying DailyCount at the end so it get persisted to database.
public int MyDailyCount
{
get { return DailyCount; }
set
{
DailyCount = value;
// your extra logic
}
}
Related
I want to change a C# class member from being an auto-implemented property (auto-property?) to use a private member variable instead, in my Windows Phone C#-based app. The change is simple except that the class represents a database table. A simplified version of the original class looks like this:
[Table]
public class ResourceItem
{
[Column(IsPrimaryKey=true, IsDbGenerated=true)]
public long m_ItemId { get; set; }
[Column(CanBeNull=true)]
private int? m_Order;
}
A bad decision years ago has led to me now need a custom getter method for m_Order. The new class looks like this:
[Table]
public class ResourceItem
{
[Column(IsPrimaryKey=true, IsDbGenerated=true)]
public long m_ItemId { get; set; }
private int? _order;
[Column(CanBeNull=true)]
public int? m_Order
{
set { _order = value; }
get { return _order == 999999 ? 0 : _order; }
}
}
This all works fine and when the unwanted 999999 value is discovered, the code returns 0, which is totally appropriate.
The original bug is not the issue, nor is the change to the class in regards to C#. The problem is with this being a database column. When I run the new app with a database created by the old version of the app, I get "Row not found or changed" errors when an object of this type is updated in the database.
Why does the update cause a problem? Shouldn't the database schema remain completely unchanged by this class change?
Using [Column(CanBeNull=true, UpdateCheck=UpdateCheck.Never)] as the column definition gets rid of the error but I would like to know why the error shows up in the first place.
Is there a different way to specify the Column attribute to avoid the error? Should I use the Column attribute on the private member instead?
And most importantly, are my database updates working correctly now that I've taken away the update check on this column?
Quick points for someone who might know the answer - is there a snippet or tool that can quickly generate template code to assign all public fields and/or properties of an object?
Example:
public class SomeBloatedClass
{
public string SomeField1 { get; set; }
public int SomeField2 { get; set; }
// etc...
public string SomeField99 { get; set; }
}
public class TestHarness
{
public SomeBloatedClass CreateTestObject()
{
// Is there a snippet/macro/template that can generate the code to assign
// all public fields/properties so they can be manually assigned quickly?
// Something like this...?
// *Begin auto-generated code
SomeBloatedClass s = new SomeBloatedClass();
s.SomeField1 = ;
s.SomeField2 = ;
// etc..
s.SomeField99 = ;
// *End auto-generated code
return s;
}
}
Third-party tools are fine as long as they integrate into Visual Studio.
Edit: I'm just looking to have the tool create empty assignment statements that I could quickly hand-edit with the appropriate values. Ideally, the solution would use the built-in snippet mechanism to navigate from statement to statement via the TAB key - I couldn't represent that clearly using StackOverflow's editor, but if you've used snippets you should know what I mean).
There is small snippet or tool that can quickly generate template code to assign all public fields and/or properties of an object?
c# property assigner tool.
and behalf of it we can also generate properties of c# ex.( get set )
c# property generator
I have an application (mvc 3) where the code is autogenerated for the datacontext class. And I need to expand the functionality, so I created partial class with the same name. But I found that only "void methods" could be marked as partial, while I need kind of a partial property.
So, is there any way to expand property's functionality in C#?
Updated:
Here is the code:
public Table<Post> Posts
{
get
{
// writing info into Trace file
Log = Console.Out;
var result = this.GetTable<Post>();
Log = new LogLinqToSql();
SubmitChanges();
return result;
}
}
The thing is that if I make any change to the data model this code will disappear, so how can I move it to the "safer" place?
Sorry for using the answer field, the post is for the discussion above:
Can't you just wrap the property from the DataContext in another property in your class
e.g.
partial class NewClass
{
public Table<Post> NewProperty
{
get
{
DoHouseKeeping();
return this.PropertyFromOtherPartialClass;
}
}
}
Only the classes need to be marked as partial.
The solution for my problem (provide logging) is simple: In the autogenerated code there is a bunch of partial helper methods. And there is a method "OnCreated" which is called when the instance of MyTypeDataContext class is created. So, I just need to do the following:
public partial class WebStoreDataContext
{
partial void OnCreated()
{
// writing info into Trace file
Log = Console.Out;
Log = new LogLinqToSql();
SubmitChanges();
}
}
If You want to add Attributes to the properties this post provides all the information)
struggling To achieve a solution for a basic Task:
working with more than one Sql Data table, as a source, for a WebSite application...
that's what leads me here once again... seeking for an Experienced C# .net Developers Help.
i was just trying to add some basic logic for a proper implementation,Like using
a dedicated namespace & classes, To Hold reference for All DATABASE tables,
(before i try working / learning about Entities Framework approach.)
i would like to try implement same of basic features of EF ...by my self, and that way... i will also learn how to properly work with classes.
as it is so far ... structured : with my little knowledge
a 'helper'.. namespace , say the company name is: HT technologies
so I've named the namespace HT_DbSchema ...that contains :
tables names
public sealed class HTDB_Tables
{
public const string Customers= "Customers";
public const string Times= "Times";
}
tables IDs
public sealed class HT_tblIDs
{
public const int tblCustomersID = 1, tblTimesID = 2;
}
tables Columns Lists ...(just one example)
public class HTDB_Cols
{
public class tblCustomers
{
public const string CustId = "custId",
CustName = "custName",
CellPhone = "cellPhone" .... etc'
}
}
and as all those 3 classes are serving all projects ..
there's another helper class for constructor Per Table For the Current Project
public class DBMetaDetails
{
public struct DbTable
{
public string TableName { get; set; }
public int TableID { get; set; }
}
}
so still these are all construction / helpers Classes and are separated from the project,
now for current project
What is The Appropriate way to get it done, using above Classes and constructor within a project
(i could name those templates)
what i was doing so far to implement some order is :
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
.... some other App inits here
}
else
{
}
// this method should be the one that instanciates the DbTable struct
//and set the values of tables name and "ID"
setTablesReferences();
}
And Here's where the confusion starts :
in a day by day usage i want to try implement it in a WebSite application :
public void setTableReferences()
{
DBMetaDetails.DbTable CustMeta = new DBMetaDetails.DbTable();
DBMetaDetails.DbTable TimesMeta = new DBMetaDetails.DbTable();
}
so now i need to set CustMeta & TimesMeta details(ids & names)
the struct has a kind of a template structure a kind'a systematic technique to initialize and assign values, so it brings some decent order to my logic with it's existence .
so what is the confusing part ?
from one point of view(safety), i need those tables detailes to be readonly
so DbTable.TableID, and DbTable.TableName would not get overWriten by mistake.
having said that, there should be only one place it could be SET ... a dedicated section of the application, like setTableReferences() above,... there i might add :
CustMeta.TableID = HT_tblIDs.tblCustomersID
CustMeta.TableName = HTDB_Tables.Customers;
on the other hand, i need the information of the tables to be Accessible,
so if let's say i would like to add those DataTables into a DataSet
DataSet ALLTablesSet = new DataSet();
// assuming the SQL actions already been taken in another method previosly...
// so DataTable is already retrived from DB
//...but only as a short usage example:
AllTablesSet.Tables.Add(new DataTable(CustMeta.TableName));
My Question is What is the Correct Way to work with structs ... as in My Scenario,
So in one section of app: you would initialize - assign it with a value privately.
and from other sections of the app you could use its value (Only For Readings)
so that way, the application will not be able to access it's value for writing,
only by reading values, i think it should be trough another (Public ReadOnly) Variable.
so that variable was meant to be exposed ...and it's value could not be "harmed"
If I understand the question correctly, the way I would prevent other code from modifying it is by removing the setters on the properties. However, you still need to set them at some point, so rather than removing the setters completely, you can just make them private. For example:
public string TableName { get; private set; }
If you do this, the only place you can set this data is within the struct itself, so you would need to create a constructor that took the initial values you wanted. So something like:
public struct DbTable
{
public DbTable(string tableName, int tableId)
{
this.TableName = tableName;
this.TableID = tableId;
}
public string TableName { get; private set; }
public int TableID { get; private set; }
}
Situation: I have a large shrink wrapped application that my company bought. It is supposed to be extensible, yada, yada. It has a DB, DAL and BLL in the form of SQL and DLLs. It also has a MVC project (the extensible part) but 95% of the "Model" part is in the DAL/BLL libraries.
Problem: I need to extend one of the "Models" located in the BLL. It is an User object with 47 properties, 0 methods and no constructor. What I started was a simple deivation of their class like:
public class ExtendedUser : BLL.DTO.User
{
public bool IsSeller { get; set; }
public bool IsAdmin { get; set; }
}
This works fine if I just create a new ExtendedUser. However, it is populated by another call into their BLL like:
BLL.DTO.User targetUser = UserClient.GetUserByID(User.Identity.Name, id);
I tried the straight forward brute force attempt, which of course throws a Cast Exception:
ExtendedUser targetUser = (ExtendedUser)UserClient.GetUserByID(User.Identity.Name, id);
I am drawing a complete blank on this very simple OO concept. I don't want to write a Constructor that accepts the existing User object then copies each of the properties into my extended object. I know there is a right way to do this. Can someone slap me upside the head and tell me the obvious?
TIA
If you do want to use inheritance, then with 47 properties, something like Automapper might help you copy all the values across - http://automapper.codeplex.com/ - this would allow you to use:
// setup
Mapper.CreateMap<BLL.DTO.User, ExtendedUser>();
// use
ExtendedUser extended = Mapper.Map<BLL.DTO.User, ExtendedUser>(user);
Alternatively, you might be better off using aggregation instead of inheritance - e.g.
public class AggregatedUser
{
public bool IsSeller { get; set; }
public bool IsAdmin { get; set; }
public BLL.DTO.User User { get; set; }
}
What about this approach (basically Aggregation):
public sealed class ExtendedUser
{
public ExtendedUser(BLL.DTO.User legacyUser)
{
this.LegacyUser = legacyUser;
}
public BLL.DTO.User LegacyUser
{
get;
private set;
}
}
I don't want to write a Constructor that accepts the existing User object then copies each of the properties into my extended object.
This is typically the "right" way to do this, unless you have compile time access to the BLL. The problem is that a cast will never work- an ExtendedUser is a concrete type of User, but every User is not an ExtendedUser, which would be required for the cast to succeed.
You can handle this via aggregation (contain the instance of the User as a member), but not directly via inheritance.
This is often handled at compile time via Partial Classes. If the BLL is setup to create the classes (ie: User) as a partial class, you can add your own logic into a separate file, which prevents this from being an issue. This is common practice with many larger frameworks, ORMs, etc.