EntityFrameworks, Linq and an optional child - linq

I have three classes, called Authors, Books and Publishers
An Author can have many Book.
A Book can have many Authors.
A Book can have one (optional) Publisher.
A Publisher can have many Books.
I want to deliver a collection of authors, books and publishers using WebAPI. I initially had a problem with JSON.Net throwing a Circular Reference exception because of the link back from the Book to the Author.
To get around this I rebuild the List returned from the repository using this:
List<Author> result = data.Select(x => new Author
{
Id = x.Id,
Name = x.Name,
Books = x.Book.Select(y => new Book
{
Id = y.Id,
Name = y.Name,
Publisher = new Publisher
{ Id=y.Publisher.Id,
Name=y.Publisher.Name,
}
}).ToList()
}).ToList();
However, I'm running into a problem when a publisher doesn't exist. How do I handle this?

It looks like you have an XY problem.
Did you try to resolve a problem with circular reference first? Check this question's answer for configuring JSON serializer to deal with circular references.

Related

What is entity reference and Query Expression ? Please give some simple examples

What is EntityReference and QueryExpression? Please give me some simple examples.
EntityReference
It is used for lookup fields in
365 – e.g. to link records via a 1 to many relationship. The lookup
field is shown on the ‘child’. You need to specify the ‘parent’ entity
type and record id.
For example if you are creating a accountand want to set the primary contact.
Entity account = new Entity("account");
account["name"] = "James Account";
account["primarycontactid"] = new EntityReference("contact", contactId);
service.Create(account);
QueryExpression
QueryExpression provides an object model to construct a query. Queries
can also be created using FetchXML, a proprietary XML based query
language.
For example of you wanted to retrieve all contacts full name and telephone number.
QueryExpression query = new QueryExpression()
{
Distinct = false,
EntityName = Contact.EntityLogicalName,
ColumnSet = new ColumnSet("fullname", "address1_telephone1"),
};
DataCollection<Entity> entityCollection = _service.RetrieveMultiple(query).Entities;

reading related data after a selection of a foreign key - MVC3 and EF4

I am new to MVC and EF and I have a question.
I have built a site with models views controllers etc.
On an edit view for a Case (pretty big model so I won't post it here) I have a FK to a Customer model using CustomerID. When a user selects a customer id from a drop down list, I would like to display CustomerName, CustomerPhone etc after the selection of the ID. I think I might need to do a post back for this to work?
Also, do I need to Include the related entities as part of the initial data "get"? I have read some detail on that but I dont fully understand how that needs to work.
Please let me know if I should post more info. Thanks!
Here is my ActionResult for Edit
public ActionResult Edit(int id)
{
Cases cases = db.Cases.Find(id);
//related data needs to loaded to show related data fields
//include related data entities
var v = db.Cases.Include("Customers");
ViewBag.TechnicianID = new SelectList(db.Technicians, "TechnicianID", "LastName", cases.TechnicianID);
ViewBag.BranchID = new SelectList(db.Branches, "BranchID", "BranchName", cases.BranchID);
ViewBag.EngineModelID = new SelectList(db.EngineModels, "EngineModelID", "EngineModelName", cases.EngineModelID);
ViewBag.CaseCategoryID = new SelectList(db.CaseCategories, "CaseCategoryID", "CategoryName",cases.CaseCategoryID);
ViewBag.Qualified = new SelectList(new[] { "YES", "NO", "PARTIALLY" });
ViewBag.CaseStatus = new SelectList(new[] { "OPEN/IN PROCESS", "CLOSED" });
return View(cases);
}
The line
var v = db.Cases.Include("Customers")
is what I am trying to use to load related customer data and then show in my edit view like this:
#Html.EditorFor(model => model.Customer.CustomerName)
Well it depends on what you are trying to do. You could include a model which holds all the required data and send it with every call on that page (initial empty ofcourse)
Once you selected the customer, do post-back and send the customerId to your application and return the same page with the desired model.
You could do that via AJAX too.
Also, do I need to Include the related entities as part of the initial data "get"?
Not sure if I understand what you are trying to say. You mean that you think you would have to send all customer's data down to the page and select the related data on client side?

How to get object collection from another collection?

Suppose I have a collection defined as:
IEnumerable<Employee> Employees;
Entity Employee has property Person.
I have loaded Employees from Ria service including Person with eager-loading.
Now I want to get the collection of Person from Employees, something like
IEnumerable<Person> People = Employees.Person;
How to use Linq to get all Person? any other solution for this case?
Unless I'm missing something, it should be as easy as (assuming Person isn't another collection):
var persons = Employees.Select(e => e.Person);
Try the following
IEnumerable<Employee> collection = ...;
IEnumerable<Person> persons = collection.Select(x => x.Person);

Dynamics crm 2011 addlink with relationship campaignlist_association

Relationship relation = new Relationship("campaignlist_association");
Entity campaign = (from c in orgServiceContext.CreateQuery("campaign")
select c).FirstOrDefault<Entity>();
foreach (Guid id in listsMarketingGuid)
{
Entity list = (from l in orgServiceContext.CreateQuery("list")
where l["listid"].Equals(id)
select l).FirstOrDefault<Entity>();
orgServiceContext.AddLink(campaign, relation, list);
orgServiceContext.AddLink(list, relation, campaign);
}
orgServiceContext.SaveChanges();
I would like to add a relation between a marketing list and a campaign but when the SaveChanges statment is executed I got an error "Associate is not supported for CampaignItem".
Do you any idea ?
Thanks
use Associate method as for building relationship:
_service.Associate(EntityLogicalName,EntityId,relationship,relatedEntities);
where EntityLogicalName is name of entity
EntityId is id of entity
relationship:wat kind of relationship
relatedentities:to which entiites u want to build relation of above entity.
it needs to call method AddItemCampaignRequest
I got the error
"Associate is not supported for CampaignItem"
when trying to associate product to campaign. This worked for me:
var request = new AddItemCampaignRequest
{
CampaignId = yourCampaign.Id,
EntityId = productToAssociate.Id,
EntityName = ProductEntity.EntityLogicalName,
};
_serviceProxy.Execute(request);
Creds to Mitch Milam
Hope this will help someone.

LINQ query for tag system: Matching any of several tags?

I am just getting started with LINQ. I am creating an Entity Framework app that uses the canonical Post and Tag model. A Post contains an ID, Text, and Tags, and a Tag contains an ID, a Name, and Posts.
A previous thread on StackOverflow showed me how to query for a Post that matches all Tag objects (A and B and C) in a search list. But how would I query for a Post that matches any Tag (A or B or C) in the list? Thanks for your help.
Stumbled over the answer right after I posted this question. PredicateBuilder to the rescue!
Here's my code, which uses PredicateBuilder. It is set up as an extension method:
public static IQueryable<Note> WhereContainsAnyTags(this IQueryable<Note> notes, IEnumerable<Tag> searchTags)
{
// Initialize
var predicate = PredicateBuilder.False<Note>();
// Select Notes that contain any search Tags
foreach (var searchTag in searchTags)
{
var tag = searchTag;
predicate = predicate.Or(note => note.Tags.Any(t => t.Id == tag.Id));
}
// Set return value
return notes.AsExpandable().Where(predicate);
}
And here is how I call the code:
searchResults = m_ViewModel.ObjectContext.Notes.WhereContainsAnyTags(m_ViewModel.SearchTags);
Not sure if this would work or not, but worth a try anyway I guess if you are already using WhereIn.
var posts = context.Tags.WhereIn(tag => tag.Name, acceptableValues)
.SelectMany(t => t.Posts);
The WhereIn should give you all the tags that are part of the name, and the SelectMany should give you all the posts containing those tags.
You could aslo do it like this with Entity SQL
var post = ctx.Posts.Where("it.Tags.Id IN (1,2,3)");

Resources