I really hope you can help me as I am about to just throw my MVC/Entity Framework project in the bin and start a MVC/Linq project.
I am building a forum as a project just to get to know MVC/Entity, and I have 4 tables which are all related.
Forum_Category,
Forum,
Topic,
Reply
so there is a 1 to many on Category_ID between Forum_Category and Forum.
1 to many on Forum_ID between forum and topic.
and a 1 to many on Topic_ID between Topic and Reply.
I understand that you can load up related data using
Dim F = (From forum in _DataContext.Forum.Include("Forum_Category") _
Where forum.Forum_ID = 1 _
Select forum).First
but what if I wanted to get the data for all the replys to a single topic, then load up the topic's forum and then the category?
I managed to get slightly there with the code:
Dim FT = (From F In _dataContext.Topic.Include("Forum") _
Where F.TOPIC_STATUS = ForumSettings.FORUM_STATUS.Active _
Select F).First()
Dim TRs = (From F In _dataContext.Topic_Reply _
Where F.Topic.TOPIC_ID = TopicID _
Select F).ToList()
For Each TR As Topic_Reply In TRs
FT.Topic_Reply.Add(TR)
Next
Return FT
But then when I tried to add a new Reply, I got the error:
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
I am totally lost now.
Dim FT = (From T In _dataContext.Topic.Include("Replies").Include("Forum") _
Where T.TOPIC_ID = TopicID _
Select T).First()
...presuming the property is called "Replies" and not "Replys". :)
Now you can look at FT.Replies to see the reply and FT.Forum to see the Forum.
Don't use Add. That's to do an INSERT into your DB, and of course those records are already there. That's what the error means.
The key insight here is that all relationships are two-way. You can see the related object from either side of the relationship.
Related
I have a project that looks up distinct orders from the database. It then creates a string of CustomerNumbers from a field in the returned orders. Then it filters the orders based on the CustomerNumbers. The issue is it only ever returns 2 customers when there should be 10. I did return a count of all customers & that also only returns 2 customers. There are a total of 667K+ customers in the database. I tried uninstalling the EF nuget package & reinstalling. I checked to make sure the repositories I have setup aren't filtering anything in anyway. I'm stuck & under the gun right. Any help would be great. Also any refactoring suggestions or EF changes are welcome too. Thanks!
var count = dbCustomer.Records.Count();
var orders = dbOrders.Records.ToList();
data.Orders = orders;
var orderCustomerNumbers = data.Orders.Select(o => oMeta15).Distinct().ToList();
var orderNumbers = data.Orders.Select(o => o.OrderNumber.ToLower()).ToList();
data.Customers = dbCustomer.Records.Where(c => orderCustomerNumbers.Contains(c.CustomerNumber)).To.List();
data.Payments = dbPayment.Records.Where(p => orderCustomerNumbers.Contains(p.OrderNumber.ToLower())).ToList();
data.Products = dbProducts.Records.Tolist();
Sorry for not getting more details out, but I did fix the issue. Originally I had issues getting the data into the database using the app(EF). To get around the issue and keep moving forward I used SSMS to import the data. Since I didn't use the app(EF), to import the data the Discriminator column was never filled in with data. Therefore the only two rows that were being returned were the rows with the correct value in the Discriminator column. After running a quick SQL statement to update all the rows with the correct Discriminator value everything is working fine now.
im trying to figure out how to Count all Items from child to child where a column called "IsVerified" is true. I got the first two childs counted (BlogPost -> Comments(child) -> SubComments(child)) but i cant figure out how to count the third child
The structure of the model is similar to this on
BlogPost -> Comments -> SubComments -> SubSubComments
I cant show you the real models so here is an example:
https://gist.github.com/anonymous/c357bfdd158cc6a392d9
Its all working instead of the third child.
I hope you can help me.
Thanks.
Something like:
// Don't need ToList here, lazy is fine
var blogs = db.BlogPosts.Include("Comments.SubComments.SubSubComments");
var count = blogs.SelectMany(b => b.Comments)
.Where(c => c.IsVerified)
.SelectMany(c => c.SubComments)
.Where(sc => sc.IsVerifier)
.Count();
will get the count of verified sub-comments in verified sub-comments.
And because I've not used ToList on the initial expression this should all be converted to SQL and executed on the server (details of the SQL will depend on the details of the model, for example whether relationships are required or not).
I want to add a prefix to a specific staff type and not to another, within a column of my report; by saying
If {staff type} = {doctor} then add 'dr' to the name,
If {staff type} = {nurse} then don't add dr
but I've had trouble finding a way to do it as the only other ways I've seen if, then formula is that they usually don't involve two tables and I don't know how to join them. They usually say; if {target} >500 then exceeded, if {target} <500 then below.
Grateful to suggestions.
Not familiar with CR syntax so please be clear.
Thanks
try this:
If {staff type} = {doctor}
then "dr " + <<Database field.name>>
else If {staff type} = {nurse}
then <<Database field.name>>
I'm new to Delphi. I got two TSQLTables (say A and B) linked to two TClientDataSets (say cdsA and cdsB respectively) by two TDataSetProviders, two DataSources (dsA and dsB) complete the scenario.
Let A be the master one and let B be the detail one.
B.MasterSource is set to dsA value and B.MasterFields value refer to a field that does not exists in cdsA (but exists in the query). When I start the application I open cdsA first and then I open cdsB. Something goes wrong. The DBGrid that link to dsA datasource shows data, the DBGrid that link to dsB does not show anything. The SQLMonitor logfile shows that the query implemented in B is executed (a simple select a, b, c from tableB ). The stuff works fine if I change the query and show the field 'X' (select a, b, c, X from tableB) where 'X' is the field referred by B.IndexFieldNames property.
Why the DBGrid that link to dsB does not show the B's record related to cdsA's current record? Does it works only if I specify the IndexFieldNames in the query columns? What did I miss? TIA.
I'll explain the complete scenario using AdventureWorks database for SQL Server 2008 R2. I'll also assume that you've already placed the TSQLConnection component and properly set its parameters to established connection with your database. For this example, I'll also assume the name for it to be Conn1.
On a form, place 2 TSQLTable (named tableA and tableB), 2 TDataSetProvider (named dspA and dspB), 2 TClientDataSet (named cdsA and cdsB), 2 TDataSource (named dsA and dsB) and 2 TDBGrid (named gridA and gridB) components.
Set properties as follows:
tableA.SQLConnection = Conn1
tableA.SchemaName = Sales
tableA.TableName = Customer
tableA.Active = True
dspA.DataSet = tableA
cdsA.ProviderName = dspA
cdsA.Active = True
dsA.DataSet = cdsA
gridA.DataSource = dsA
tableB.SQLConnection = Conn1
tableB.SchemaName = Sales
tableB.TableName = SalesOrderHeader
tableB.Active = True
dspB.DataSet = tableB
cdsB.ProviderName = dspB
cdsB.MasterSource = cdsA
cdsB.MasterFields = CustomerID
cdsB.Active = True
dsB.DataSet = cdsB
gridB.DataSource = dsB
In gridA you should see all Customers, and in gridB you should see only Orders related to curently selected customer.
This is the basic example of establishing master/detail relationship between two TClientDataSet components in Delphi. However, there are other ways to do this.
The way that I link ClientDataSets is outlined in Cary Jensen's book "Delphi In Depth: Client DataSets". Setup the Master and Detail datasets as per normal, and ensure that they are linked via a TDataSource (you will have a parameter in the Detail SQL that links it to the Master). However, CJ suggests then having only one DataSetProvider which is attached to the Master. But the master (and therefore the DSP) will have a Nested DataSet reresenting the detail table. The detail / nested dataset can appear in the master table DBGrid or in its own DBGrid. Your gridB will get linked to the Nested Dataset.
The problem in linking gridB directly back to the TSQLQuery (as I understand) is that any updates to the master CDS are not reflected in gridB. If you want to see more then you can download the project NestedFromMasterDetail from Cary's web site.
If you really want to know more, then buy a copy of Cary's book. I have found it invaluable in understanding Client Data Sets. They are setup somewhat different and Cary does a good job of explaining their architecture.
I'm just getting up to speed with asp.net mvc and I'm wondering how one would go about getting relational data more than one level deep from the entity specified in the from clause. Using the following domain model as an example:
A Blog has many posts. Posts have many comments.
How would I write a LINQ query to return entities down to the Blog.Posts.Comments level?
The only (not so elegant) solution I came up with was to use a LINQ query to get Blog and Posts and then a foreach to get comments.
var blog = (from b in _db.BlogSet.Include("Posts")
select b);
foreach (Post p in blog.Posts)
{
var comments = (from c in _db.CommentSet
where c.PostId = p.Id
select c);
p.Comments = comments;
}
A Blog has many posts. Posts have many comments.
How would I write a LINQ query to return entities down to the Blog.Posts.Comments level?
I believe, you could do the following to achieve this:
var blog = (from b in _db.BlogSet.Include("Posts.Comments")
select b);
In this case, for each blog, the posts and their comments will be fetched.
Marc
You can just use two from statements:
var comments=from post in blog
from comment in blog.comments
where comment.PostId==post.Id
select comment;