Linq - How to put common fields in a base class - linq-to-sql

I am trying to find a way so that I can push some common functionality into a base class for my Linq to SQL processing. I have two fields (ID and InsertUpdateOperID) that are common to most but not all of my tables. In my first go around I created a class called BaseEntity that had these fields. Unfortunately all I accomplished was hiding from the values in the .designer.cs file. I found an example of how to accomplish what I wanted In order to get around this (http://www.joe-stevens.com/2009/07/01/linq-to-sql-set-inheritance-modifiers-with-sqlmetal/). As per this article, I modifed the DBML file so that I could add the override modifier to the ID and InsertUpdateOperID properties on the tables that contained these two fields.
The net result of this was that the .designer.cs file added the override qualifier where I wanted it. This enabled me to create my BaseEntity class. Where I defined the ID field and the InsertUpdateOperID field as:
public virtual int ID { get; set; }
public virtual int InsertUpdateOperID { get; set; }
Doing this seemed to work fine.
The problem for me is that I hate the idea of modifying generated code. Can anyone suggest a way for me to put common fields and methods that act on those common fields in a base class so that I could accomplish what I want without modifying the generated .dbml?
Thanks

I'm facing the same problem today (wow, it's 1.5 years after your post), and struggled out a solution, so far it's good for me.
in the base class:
public virtual int __ID
{
get
{
PropertyInfo pi = this.GetType().GetProperty("ID");
int id = (int)pi.GetValue(this, new object[] {});
return id;
}
set
{
PropertyInfo pi = this.GetType().GetProperty("ID");
pi.SetValue(this, value, new object[] { });
}
}
This looks quite voilent, but it works!
Notice the __ before ID, because there is alread ID and _ID in the auto generated codes. As it's totally a new third way to access ID, no "override" is needed.
And if you need, you can use the __ID in or via your base class.

Related

Unknown Column In Field List - Field Does Not Exist on Entity

I'm having an issue figuring out where Entity Framework is getting the list of column names to query from a MySQL database. Essentially, when I am querying my context for a list of Discounts, a seemingly random property is getting attached, which doesn't exist in the database. I can't seem to find where, so I'm hoping someone has some troubleshooting guidance for me.
I have a Discount entity, that inherits off of my 'EntityBase' class.
public class Discount : EntityBase
{
public Discount(){}
}
public class EntityBase
{
public int Id { get; set; }
}
When I attempt to query discounts...
var discount = _myContext.Discounts.FirstOrDefault();
I get the following error - Unknown column 'd.AttendeeBadgeId' in 'field list'
Now, I DO have an AttendeeBadge entity, and I have a variety of other entities that utilize the AttendeeBadge. But I have absolutely nothing in the Discount class that utilizes the AttendeeBadge entity. I just have the Id property that gets inherited through EntityBase - and yet, my generated MySQL query is...
SELECT `d`.`Id`, `d`.`AttendeeBadgeId`
FROM `Discount` AS `d`
LIMIT 1
I've validated that in my modelBuilder for my context, I'm not mapping any particular properties that would cause an issue.
modelBuilder.Entity<Discount>().ToTable("Discount");
modelBuilder.Entity<Discount>().HasKey(_ => _.Id);
I thought something might be cached, but I've deleted all of the bin/obj folders for every single project in my solution, and I used Notepad++ to validate all of the areas that I reference the string value "AttendeeBadgeId", and I just get the other classes that reference it.
I'm at a loss here, would anyone know how I could see how the context is generating the SQL query in a more verbose way, or see where that column is coming from?
I should have tried harder before posting.
It turns out I had a property on the AttendeeBadge entity that had a list of Discounts.
public class AttendeeBadge : EntityBase
{
public AttendeeBadge ()
{
Discounts = new HashSet<Discount>();
}
public ICollection<Discount> Discounts { get; set; }
}
This was causing Entity Framework to assume there was a relationship between the Discount and the AttendeeBadge when I removed that dependency earlier today. I found out by copying the Discount class to another class, and then re-mapping my entities until I found the culprit causing my issue.

Override virtual methods in partial classes that are generated

In my LINQ generate class, I have this method:
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Id",
AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY",
IsPrimaryKey=true, IsDbGenerated=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();
}
}
}
In my coded partial class, I extend from a base class. The base class defines:
public virtual int Id { get; set; }
The concept is that I can add the Equals and Hashcode at the base class level, as well as some other functionality at the base class level. The problem is that the generated classes (from LINQ-to-SQL) do not get an override keyword so it doesnt work. If it had override I would be all set.
Please suggest on how to complete this.
You could make the base class abstract, and then the Id property becomes
public abstract int Id { get; set; }
The generated code will implement that abstract property.
A partial class is different from overriding a class. With a partial class you're just saying. Ok, i have 1 class but i have splitted the source up over multiple files (mainly for maintainable reasons like splitting the auto generated code from your own code). The C# compiler just merges each part of a partial class together and threats it as 1 class. Ofcourse overriding a class means you create a new class which takes on the characteristics of the base class. That is very different.
Now it's possible but not relatively easy to direct EF of how to generate your code (assuming you are using EF). One option you can do though is to change your base class not to work with the Property Id but a more recognizable (and specifix?) name like 'CompareIdentifier'. With that you can override CompareIdentifier in your derived class for returning the auto generated ID. And ofcourse do all comparison work against CompareIdentifier
I would have created a wrapper class around this.

EF 4.1 Code First doesn't create column for List<string>

I have been playing around quite a lot with EF4 Code First and I do love it. However, I cannot seem to sort this easy one out.
When trying to create something like this, no columns are created in my database:
public IList<String> Recievers { get; set; }
public List<String> RecieversTest { get; set; }
public virtual List<String> RecieversAnotherTest { get; set; }
public virtual ICollection<Int32> RecieversAnotherTest { get; set; }
Ive tried Annotations to map it to a different column name, I've tried IEnumerable and all sorts of other collections, but it refuses to create a column for it.
After an hour on google I found one that claims she has done it, but I'm starting to doubt that. Should it even be possible?
I can't really see why it just doesn't create a column and use JSON or CSV.
It can't be that rare, can it? In my case i just want to store a list of emails.
What am I missing? The project creates all other types without problems, and I've inspected the database to see how other properties I add to test with gets created, while these gets ignored.
So the problem must lie in some setting I'm missing or some configuration....
EF 4.1 RTW on an SQL Server 2008 db.
I have bad news for you. EF doesn't do anything like that. If you want any serialization and deserialization you must do it yourselves = you must expose and map property with serialized value:
private IList<String> _receivers;
// This will be skipped
public IList<String> Receivers
{
get
{
return _receivers;
}
set
{
_receivers = value;
}
}
// This will be mapped
public string ReceiversSer
{
get
{
return String.Join(";", _receivers);
}
set
{
_receivers = value.Split(';').ToList();
}
}
Now ReceiversSer will be mapped to a column in the database.
You can't have a column based on a collection/list of something. A column is a singular item such as public string Receiver.
If you are expecting EF CF to take your IList or List and make several Columns out of it you are correct in that it won't.
In EF CF you create lists in your Entity to represent a relationship to another table. An Order may have many Items in it. You would in this case have an Order class with a list to an OrderItem object.
You would then have an OrderItem class to describe the OrderItem table. This would then essentially represent the 1 to many relationship of Order and OrderItems.

Mapping a field name beginning with an underscore in Entity Framework 4.1 Code First

I have a class that contains a few private/protected fields and some public getters that return the value of the fields. I am attempting to map the fields to database columns using the fluent API on the DbModelBinder in OnModelCreating. I cannot use an automatic property with a protected setter so please don't offer that as a solution to my question. It would probably work I'm sure but I cannot use the automatic property as the domain class is shared code and used with other different ORMs that have different ways of mapping their fields and unfortunately one doesn't support the au
I use the following code (found on stackoverflow) to access the protected field so that I can use the expression when mapping:
public static class ObjectAccessor<T>
where T : class
{
public static Expression<Func<T, TResult>> CreateExpression<TResult>(string propertyOrFieldName)
{
ParameterExpression param = Expression.Parameter(typeof(T), "propertyOrFieldContainer");
Expression body = Expression.PropertyOrField(param, propertyOrFieldName);
LambdaExpression lambda = Expression.Lambda(typeof(Func<T, TResult>), body, param);
return (Expression<Func<T, TResult>>)lambda;
}
}
This all works wonderfully if the field name is m_username but if I use _username I get a ModelValidationException: One or more validation errors were detected during model generation: System.Data.Edm.EdmProperty: Name: The specified name is not allowed: '_username'.
I can't use camelcase without the underscore either as the helper above can't distinguish between the public Username property and the protected username field. I'd really like to still keep using the underscore camelcase without the letter prefix.
Is it possible to configure the ModelBinder in some way so that the validation accepts the property name with a leading underscore?
Thanks in advance,
Mark
It seems that decoration of your field like this :
[Column("username")]
public string _username
maybe helpful in your case, anyway - please review similar case

Saving and Retrieving Entities of different types using LINQtoSQL

Disclaimer: Bit of a C# newbie - first Software Dev gig in awhile after being in QA for a couple years.
I realize flavors of this question have been asked before (inheritance in LINQtoSQL and the like), but I'm hoping I ask the question differently.
In my database, I will have a super-type of "Event" and multiple sub-types: Conference, Meeting and Appointment, for example.
Event
Id (PK)
TypeId (FK EventTypes.Id)
Title
Conference
Id (PK, FK Event.Id)
Cost
Topic
Meeting
Id (PK, FK Event.Id)
Location
Organizer
Appointment
Id (PK, FK Event.Id)
Time
Address
I am using Rob Conery's MVC StoreFront application as a reference. He essentially gets data from the database and creates class objects, manually mapping Event.Id to db.Event.Id, etc.
I'd like to do this with my Events data model - I'd like to retrieve all Events, and have a LINQ expression dynamic enough to create various event types based on some criteria (TypeId, for example).
var result = from e in db.Events
select new IEvent
{
// Little help? ;)
};
It would be great to find a way to make it so each Event Type knows how to save itself and retrieve itself - I fear having to write the same code for each type, only varying the fields. Make sense?
I did see a question posed and someone answered with something like:
public bool Save<T>() {}
The problem is, I'm not sure where to put this code. I'm also not sure if I should use an IEvent interface or an Event partial class.
I will now end this monster question with an advanced Thank You to those that can offer help/suggestions.
--
EDIT: Good progress - going from DB to Views all with IEvent :) (This Question Helped A Lot)
public class SqlEventRepository : IEventRepository
public IQueryable<IEvent> getEvents() {
// Get Events without doing a query for each type..possible?
var eventType1 = {query};
var eventType2 = {query};
return {concat of all queries};
}
public bool SaveEvent(IEvent) {
// Can I avoid calling a save function for each type of event?
}
You could have a helper class to put your Save<T>() method in. Something like SaveEvents class.
When you want to save using LINQ I'm not so sure that you can use generics as you don't know what T is and therefore cannot update properties in your queries.
I'd use inheritance and then where you'd pass a sub-class, use the parent class (Event) as your argument. Then you can quite easily cast to your subclasses to access those properties in your LINQ Queries.
EDIT:
Something like this:
public class Event : IEvent (Interface implement common properties to all Event type classes)
{
// your code
}
public class MeetingEvent : IEvent
{
public string MeetingEvent
{
get;
set;
}
// add IEvent implementation...
}
public class EventManager
{
public void MyMethod (IEvent event)
{
MeetingEvent Mevent = (MeetingEvent)event;
Mevent.DoSomework();
// now you can cast all eventclasses to and from IEvent passed as a parameter.
}
}