My intent is to create a generic (not in C# meaning) database model for Windows Phone using linq to sql. User of such model should be able to pass an array of his data object types (classes marked with Table attribute) to model's contstructor, and then model should take care about adding related tables to database and provide API for CRUD operations.
But then I've found out that in order to add tables to database, your data context (class inherited from DataContext class) have to declare each table as a property! That's embarrassing. Does this fact mean that my idea is not implementable? Because I obviously cannot add properties to my DataContext-based in the runtime.
So my question is, am I right in my judgments? If yes, are there some workarounds to solve this issue?
Thanks in advance.
EDIT: better question tagging, for somebody finally notice this.
You do not need to use a strongly typed DataContext (a class inheriting from DataContext and declaring properties for each table). You can do something like the following instead
var context = new DataContext("connection string", new AttributeMappingSource());
var table = context.GetTable<T>();
where T is some type marked with the Table attribute.
Related
If I want to select only few columns when retrieving data for an EF entity and cast them to the Entity type, I am not able to do that because it throws an error as mentioned in this post
The entity cannot be constructed in a LINQ to Entities query. I don't want to select all the columns, because I need only few of them. I can use anonymous types, but if I am using repository pattern and want to encapsulate all data access code in repository object and pass strongly typed object collection to the controller (not an anonymous object collection), how can I achieve that? Is the only option to define a DTO object for every subset of the properties for the EF entity? I know there is a risk of losing data with partial loaded entities, but if I am ready to take the risk and want full control over data updates, is that not possible?
for example I would like the "ProductRepository" method signature to be like this
public IEnumerable<Product> GetProducts(int categoryID) //selection of subset of data
and I want to pass this product collection from the controller to the view (in ASP.NET MVC project) and in the view I want to have strongly typed model (with intellisense) object. Is this possible? if not, I may have to reconsider using EF for my project due to this limitation. I am using EF 4.1 version.
Yes the option in this case is special object for each subset of properties you want to select. You can call the object DTO because it is just a result of the projection. This is the correct approach because if your UI doesn't need other properties of entity type it is correct to pass it only specialized ViewModel.
Another more complex (and worse) option is selecting anonymous type inside your Linq-to-entities query, calling ToList and after that construction the real entity type. Partial entity selection is not allowed and projecting to mapped entity types is not allowed as well. That is the reason why you have to use such a cumbersome approach. Example:
// Select anonymous projection
var query = from x in context.Entities
where ...
select new { ... };
// Repopulate entity type
var reultSet = query.ToList().Select(x => new Entity { ... });
Yes, what you want is totally possible using viewmodels instead of entities. Here is example controller code:
var productEntities = productRepos.GetProducts(6);
var productViewModels = Automapper.Mapper
.Map<IEnumerable<ProductViewModel>>(productEntities);
return View(productViewModels);
Your view model will have only the properties it needs for the view. Check out automapper.
I have a table called Code in my LINQ to SQL datacontext. I also have a class called Codes in my Models folder. What I want to do is save the updated object Codes to my database table Code. Is this possible?
In my controller, I would pass the edited Object to my Model. My CodesRepository file contains this:
public Codes EditCode(Codes CodeToEdit)
{
private EventsDataContext _db = new EventsDataContext();
Codes C = new Codes();
C = CodeToEdit;
_db.Codes.InsertOnSubmit(C); //error here, something about invalid arguments
//InsertOnSubmit is for adding a new object, but I don't know the syntax
// for editing an existing object.
_db.SubmitChanges();
}
This is probably not the correct way of doing this so can someone point me in the right direction? Do I even need a class called Codes or do I need to somehow just use my database table? Thanks.
Solution: I decided to change from Linq to SQL to an Entity Framework and it works much better. This way, I don't have to define my Codes class since it comes straight from the database and I was able to delete the Codes class file.
You should use DataContext.Attach when you get an object back that corresponds to en existing row in the database. For Linq-to-sql's optimistic concurrency handling to work this requires that you either have the original, unsaved object available, or that you have a TimeStamp column in the database. The latter is preferred, as it only requires one extra field to be handled (probably through a hidden field in the web form).
1 (mvc3) I have added a stored proc to my model as mapped to a ComplextType.
Two Issues:
1) ComplextType.cs exists in class under Model1.tt BUT doesn't show up in .edmx?
2) When I try to create a controller with strongly typed views with that ComplexType.cs it errors stating that it can't be created because ComplextType.cs is not part of the DbContextEntities class?
How can I get this complex type added to the .edmx and mapped to my dbcontext (I have done this with tables but not sure what I'm missing for the stored procedures?
Thanks!
For those who just came here from googling,, :)I will give the what is basically has to be done to map a stored procedure into a ADO.Net entity.
When mapping the Database to the EDMX file(Entity Model).. the Entity Model automatically map the tables and complex types and ect.. But the stored procedures that are created in the database is not mapped with return complex types. We have to map it in the Function imports by creating our own complex type. This complex type can be accessed in the code.
This is done as below:
Right click on the function Import and add new Function import.
Give your name to the function and specify the stored procedure and
then select complex type(If stored procedure returns complex type)
or you can select scalar. IF you are selecting the complex type and
you can view the columns that are returning and you can create a complex there by create new complex type.
So the return data from the stored procedure will be a set of those complex type.
One thing that should be one should access the design or the model view to update the Entity Model. You can not update the Entity Model by just right clicking on the Entity Model. The option of updating the model is provided only on the Model Browser and the Database design diagram. This model browser can be taken from the Other windows of Views in VS2010/VS2012. These information will seems boring. But trust me if you are new to this these seems big at the beginning.
Most probably you are going to create this Entity Model from mapping an existing database.
Keep in mind that even you map the Entity model form the database you can customize the Entity model by deleting the unnecessary entities(tables) and creating complex types
I'm using stored procedure in LINQ, i know it will generate a class T(procedure name + "Result") for me automatically to store the data.
If the name of stored procedure is spCampus, the generated class will be spCampusResult.
My Question:
when i'm using SP should i create custom class that replicate all the properties ( i'm refering to whatever the .dbml creates when you drag and drop the SP)
in my situation i will be using SP... is that fair to say i will be treating as a class object and pass around from model to controller and to view ?
or i will be better off creating a new custom business object contining all the props from .dbml ?
i havent get any clear cut answer
anybody?
In the designer you can shape the object any way you see fit. You can change the names of the properties you can change the name of the object returned from the sproc if you want to. It is also my understanding that you can change the protection levels on the properties as well. This to me means that you can use the LINQ2SQL generated objects as your DTO's or you business objects because you have the power to shape them as you see fit in the designer and since they are partial classes you can extend their behavior without touching the generated class. Hope this helps.
Have been trying out the new Dynamic Data site create tool that shipped with .NET 3.5. The tool uses LINQ Datasources to get the data from the database using a .dmbl context file for a reference. I am interseted in customizing a data grid but I need to show data from more than one table. Does anyone know how to do this using the LINQ Datasource object?
If the tables are connected by a foreign key, you can easily reference both tables as they will be joined by linq automatically (you can see easily if you look in your dbml and there is an arrow connecting the tables) - if not, see if you can add one.
To do that, you can just use something like this:
<%# Bind("unit1.unit_name") %>
Where in the table, 'unit' has a foreign key that references another table and you pull that 'unit's property of 'unit_name'
I hope that makes sense.
(EDIT misunderstood the question, revising my answer to the following)
Your LinqDataSource could point to a view, which allows you to overcome the problem of not being able to express a Join in the actual element. From "How to: Create LINQ to SQL Classes Mapped to Tables and Views (O/R Designer)":
The O/R Designer is a simple object relational mapper because it supports only 1:1 mapping relationships. In other words, an entity class can have only a 1:1 mapping relationship with a database table or view. Complex mapping, such as mapping an entity class to multiple tables, is not supported. However, you can map an entity class to a view that joins multiple related tables.
You cannot put more than one object/datasource on a datagrid. You will have to build a single ConceptObject that combines the exposed properties of the part Entities. Try to use DB -> L2S Entities -> ConceptObject. You must be very contrived if the DB model matches the ConceptObject field-for-field.
You are best using a ObjectDataSource when you wnt to do more complex Linq and bind your Grid to the ObjectDataSource.
You do however need to watch out for Anonymous types that could give you some trouble, but anything is posible...