Entity framework result discrepancy for a database views - linq-to-sql

I have one specific view created in my DB(joins about 5-6 tables with a left join).This view is added to my edmx (entity framework 1.0) . Recently I noticed that one of the column records obtained using the edmx (linq to entities and then ToList()) got duplicated multiple times though in the database view they were different
Column-N (Expected result/ result from DB view)
---------
data1
data2
data3
data4
data5
Column-N(Actual result generated by entity framework)
---------
data1
data1
data1
data1
data1
I fired up my SQL profiler,got the query which was sent by my application to the SQL Server, ran it and it returned me the expected result.
MSDN has a similar post here and here but the moderator has not elaborated on how to solve this problem. My key happens to be a GUID
The root cause you pointed out I think
is correct, the problem is on the
application side EF mapping, as EF has
different object mapping rules with
database. when the query results have
been returned from database, the EF
will do the mapping on application
memory according to its own designed
logic.
It's important to take these logic
into account when you desingn your
view query in your database side. I
think you should do some adjustment on
your view query.
I am not sure whether you have sorted
the problem, if not please provide the
database structure related to this
issue and the view query you have
written.
Thanks Binze
Has someone encountered a similar problem before ?

The problem is in fact with the key. You have to a) have a unique identifier for each row in the view. and b) map that key accordingly in the edmx. Otherwise as your quote states, the mapping logic will see each subsequent row and figure that it can use the same object instance that it returned before

Same problem for me.
An Entity View (VReport) was generated automatically from VS2010 wizard to something like:
class VReport
Line: int (key)
Desc: string
Date: DateTime
When I retrieved the records from the database, the SQL query was formed correctly and returned the expected (and distinct) results, but the Entity Framework instead returned a lot of duplicated records.
But instead, also the Date column/field would have to partecipate in the formation the Entity KEY
So, to resolve this issue, I changed the property of the field from Entity Key: false -> true
class VReport
Line: int (key)
Desc: string
Date: DateTime (key)

Related

Query designer returns an unwanted entity field

I have a Reporting Services Project on SQL Server 2008 R2. The point is to provide users with a data model they can use as a data source for Report Builder 3. So I have created my data source views as usual and then the Report model with no problems.
For example in my model I have a table Student which has a relationship with table Course using a CourseSK key (one to one). So I am using student.CourseSK = course.CourseSK to return to the query designer only the course.Coursename field under the Student entity (I have hidden everything else from the course table.)
The problem is that when I test it in ReportBuilder, using the query designer when I add field CourseName from entity student in the dataset, it returns two fields instead of one: CourseName and Course where course returns some values like AAAAAEAA =. I guess is some object reference but can be very confusing to the end user. How can I make this disappear?
Indeed it turns out to be a unique entity identifier used for aggregating fields with non unique values. It cannot be removed from the data set. More information here Answer

How to include related entities in an Entity Framework Core 1.0.1 raw query?

Setup:
ASP .NET Core 1 Web API
MySQL Server Community Edition 5.7
Entity Framework Core 1.0.1 with Pomelo MySQL driver (3 separate contexts, 3 separate databases).
Contexts: MainContext (maindb), Module1Context (module1db), Module2Context (module2db).
I want to execute a query that returns a list of Posts (from Module1Context), but I need to filter them by author rights (from MainContext, User entity).
So, what I am trying to do is execute a query with a JOIN clause to a different database table:
var results = await module1Ctx.Posts.FromSql("select * from `module1db`.`posts` as `p` inner join `maindb`.`users` as `u` on `p`.`AuthorId`=`u`.`Id` where <conditions here>").ToListAsync();
When this executes, I get a SQL Exception telling me that "Sequence contains more than one element". If I select p.*, it will work, but I also need to pull the user data.
The Post entity contains a reference to the user ID (public long AuthorId {get;set;}), and a fake navigation property, NotMapped, as EF couldn't join 2 databases automatically.
My first question is - would this be possible. I have a strong feeling that this will work, but that I am missing something small.
If this doesn't work, I will resort to manually executing the query, using the DbContext's Connection. If I will do this, how can I map the results into a list of Posts, including the User data?
Sequence contains more than one element
This tells you that a column appears more than once. For example if you have "ModifiedDate" column in both tables, when you do select * it will appear twice in the result set (once p.ModifiedDate and once in u.ModifiedDate.
Also additional to this, the columns returned must exactly match the model. No property which is defined in the model must be missing, that's why p.* will work.
But unless your Post model does define fields which represent values from User table, you can't return them, because it must exactly match Post and it's mapped properties.
Ad-hoc support (mapping result to an arbitrary model, like a view model) is not yet implemented in EntityFramework Core 1.0 and is a feature on the roadmap for future versions.
From the EntityFramework Core Roadmap:
Critical O/RM features
...
Raw SQL queries for non-Model types allows a raw SQL query to be used to populate types that are not part of the model (typically for denormalized view-model data).
Edit
Also from the EFCore documentation
Limitations
There are a couple of limitations to be aware of when using raw SQL queries:
SQL queries can only be used to return entity types that are part of your model. There is an enhancement on our backlog to enable returning ad-hoc types from raw SQL queries.
The SQL query must return data for all properties of the entity type.
The column names in the result set must match the column names that properties are mapped to. Note this is different from EF6.x where property/column mapping was ignored for raw SQL queries and result set column names had to match the property names.
The SQL query cannot contain related data. However, in many cases you can compose on top of the query using the Include operator to return related data (see Including related data).

Inserting records with Nested ClientDataSet with autoincrementing link

I'm teaching myself Delphi database programming using a MySQL database. I'm trying to add a record from a nested ClientDataSet with the link between master and detail tables an autoincrement field in the master table. I found a question/answer pair that appears to answer my question at: Inserting records with autoincrementing primary keys
The thing I don't understand is setting the required flag in the Query. I can't figure out how to do that as I'm too inexperienced, nor do I understand why it is necessary.
Similar to the question linked above, I have a
(SQLConnection->TSQLDataSet->DataSetProvider->ClientDataSet using dbexpress.
| |->LinkDataSource
->TSQLDataSet2->LinkDataSource
I load data into my nested ClientDataSet fine, so the component links to create the nested structure work. After loading the master/detail tables into the nested dataset, the following code gives an error.
MasterCDS1.Append;
MasterCDS1.FieldByName('TLNo').Required := False;
MasterSDS.FieldByName('TLNo').Required := False; { Error: Field 'TLNo' not found }
MasterCDS1.FieldByName('TLNo').ProviderFlags := [pfInWhere, pfInKey];
{ ... Populate Master table Fields}
MasterCDS1.Post;
MasterCDS1.ApplyUpdates(0);
TLNo is the field linking the tables and part of the primary key of the master table, and part of the primary key of the detail table. The third line where I try to set the TSQLDataSet generates the error shown in the comment. MasterSDS is where I put my 'Select * from master' query. MasterCDS learns the Schema from this query and that the field TLNo is a required field in both master and detail MySQL tables. That third line of code is my "interpretation" of what Mr Uwe Raabe said to do. Clearly I did this wrong. Can someone provide a code example so that this Delphi noob won't misinterpret the instructions? Thanks in advance.
The only reason I can imagine for the error you describe is that MasterSDS is not open when you execute that third line. "Field not found" raises either when the field does not exist in the table or the dataset (i.e. query in this case) is not open and has no static fields defined.
This leads to another point I want to mention: place the Required and the ProviderFlags settings in the AfterOpen event of the corresponding dataset. There is no need to repeat these settings whenever you append a record. If you work with static fields you can even do these settings in the Object Inspector.
For being a starter I suggest you always use static fields which can be adjusted inside the IDE. This will simplify things significantly.

INSERT with Linq omitting some "fake" columns

I have a table in the database with the following columns: ID, Name, Txt. We are using Linq To Sql to implement our DAL. In there another collegue added two extra columns so in the code the same table results: ID, Name, Txt, NameTemp, TxtTemp.
These two "fake" tables are used in different parts of the code in LINQ joins and analyzing with SQL Profiler the parsed SQL query takes the "real" columns and everything works properly.
Now I need to make an INSERT using that table, but I get an exception since also the fake columns are used in the statement.
Since I cannot add the two fake columns in the DB(since unuseful there), is there a way in which I could make an insert with Linq omitting these two columns?
I think i know where you're getting at. You should be able to add properties to a partial linq class no problem, only thing is that if you try and use a linq query against these "fake" columns, you'll get an exception when linqtosql tries to reference a column that doesn't exist in the database. I've been through this before - i wanted to be able to select columns that don't exist in the database (but do in the linq2sql dbml class) and have linq2sql translate the columns into what they really are in the database. Only problem is that there's no real easy way to do this - you can add attributes to the "fake" properties so that linq2sql thinks that NameTmp and TxtTmp are in fact Name and Txt in the sql world, only problem is that when it comes to inserting a record, the translated sql specifies the same column twice (which SQL doesn't like and throws an exception).
You can mark the column with IsDbGenerated = true - that'll let you insert records without getting the double column problem, but you can't update a record without linqtosql complaining that you can't update a computed column. I guess you can use a sproc to get around this perhaps?
I logged a bug with Microsoft a while back, which they'll never fix. The info here might help you get what you need -
http://social.msdn.microsoft.com/Forums/eu/linqtosql/thread/5691e0ad-ad67-47ea-ae2c-9432e4e4bd46
https://connect.microsoft.com/VisualStudio/feedback/details/526402/linq2sql-doesnt-like-it-when-you-wrap-column-properties-with-properties-in-an-interface
LINQ is not for inserting data, but for querying only - Language INtegrated Query. Use ADO.NET for inserting the data.
(Leaving the first part to remind my stupidity)
Check ScottGu. The classes generated are partial (mentioned here), so you can put your 2 properties into the editable part and since they won't have any mapping attribute defined, they won't be mapped nor persisted.

LINQ to Entities not returning expected result

I am using a view to return a complex search query. When I usin linq to query against EF it is returning the same row 3 times(the actual rowcount is correct).
using LinqPad I have run the same linq against my ef entity and the actual database view.
ReadmitPatientList
.AsQueryable()
.Where("PatientLastName.StartsWith(\"cooper\")")
.OrderBy (rpl => rpl.PatientLastName)
.Dump();
That is the linq I am using for both.
linqpad shows the lambda as this:
EF:
ReadmitPatientList.MergeAs (AppendOnly)
.Where ( => .PatientLastName.StartsWith ("cooper"))
.OrderBy (rpl => rpl.PatientLastName)
DB
ReadmitPatientList
.Where ( => .PatientLastName.StartsWith ("cooper"))
.OrderBy (rpl => rpl.PatientLastName)
I cannot post the results...but EF returns three rows of the same record. DB returns 3 rows of individual records. As does my sql query.
What about my EF LINQ do I need to change to make it work correctly?
The sql code that is generated by the EF Linq query Actually returns the correct results if run in SQL explorer.
This happens if Patient entity doesn't have primary key or columns inferred as primary key are same across multiple records in the result set. EF uses internally identity map which requires that each uniquely identified record must reuse the same instance of the entity. So if you return three records from the database which have same unique identification for EF will return enumeration of three same instances representing the first record from the result set (more about identity map also here). The same behaviour is in Linq-to-sql's DataContext.