3

I have a function that (via ajax) I pass a Guid and a comma delimited string of the types of objects I would like to return . I'm having trouble building a link statement that only returns the desired types. I'm struggling with how to build the query to check if string[] relatedTypes matches rw.GetType().Name. Or perhaps there's a better way.

Here's the Model...

public abstract class WebObject : IValidatableObject
{
    public WebObject()
    {
        this.Id = Guid.NewGuid();
        RelatedTags = new List<Tag>();
        RelatedWebObjects = new List<WebObject>();
    }

    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public Guid Id { get; set; }
    public virtual ICollection<WebObject> RelatedWebObjects { get; set; }
    public IList<Guid> RelatedWebObjectIds { get; set; }
}

And here's my function

public JsonResult GetRelatedWebObjectsByWebObject(Guid id, string relatedWebObjectTypes)
{
    JsonResult result = new JsonResult();
    Guid webSiteId = db.WebObjects.Find(id).WebSiteId;
    string[] relatedTypes = relatedWebObjectTypes.Split(',');
    var resultData = (from w in db.WebObjects
                      where w.Id == id
                      from rw in w.RelatedWebObjects
                      where rw.GetType().Name.Contains(relatedTypes)
                      select rw.Id).ToList();

    result.Data = resultData;
    result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
    return result;
}

4 Answers 4

2

Are you looking for something like:

var relatedTypes = new HashSet<string>(relatedWebObjectTypes);
var resultData = (from w in db.WebObjects
                  where w.Id == id
                    &&  relatedTypes.SetEquals
                          (w.RelatedWebObjects.Select(rwo => rwo.GetType().Name))

                  select w.RelatedWebObjectIds).ToList();

Although I would say that it isn't good practice to use a collection of simple type names in this manner. Are you sure you couldn't use a Type[] or similar here?

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the response Ani. The arguments are being passed via ajax from the client and the client is basically building the string[] from the jquery-ui-tab utility. So I think I'm stuck with an array of strings. I'm going to look into your answer...I'll let you know how this works out. Thanks again.
This looks like a LINQ-to-something query. And I doubt LINQ providers support HashSet<T>.SetEquals().
got the error LINQ to Entities does not recognize the method 'Boolean SetEquals(System.Collections.Generic.IEnumerable'1[System.String])' method, and this method cannot be translated into a store expression.
0

It's not clear from your question what exactly do you want, but I think it's this:

from w in db.WebObjects
where w.Id == id
from rw in w.RelatedWebObjects
where relatedWebObjectTypes.Contains(rw.GetType().Name)
select rw.Id

This selects all the items from WebObjects with the correct Id (I guess there should be only one, but it does not matter to the query). And for each of them, get the RelatedWebObjects whose type's name is in relatedWebObjectTypes. And for each of those, get their Id.

2 Comments

thanks svick. Your assumption of what I'm looking for is correct. I'm getting the error LINQ to Entities does not recognize the method 'System.Type GetType()' method, and this method cannot be translated into a store expression.
Then I guess you can't do it like this. Can you get the type of the entity in some other way? Like getting the value of discriminator column or something? If not, you would have to get all items, and filter them by the type in memory using LINQ to objects.
0

You would need to refactor a bit, instead of passing in the name of the types as string, you should pass the actual type then use the linq operator for OfType(Of relatedType)

The MSDN Article gives a simple example that should have you on your way.

1 Comment

I should have been more descriptive, and I'll change it above, but this being sent via ajax from the client so I wouldn't be able to pass the actual type.
0

A little late, but here's what I ended up going with...

public JsonResult GetRelatedWebObjectsByWebObject(Guid id, string relatedWebObjectTypes)
    {
        JsonResult result = new JsonResult();
        Guid webSiteId = db.WebObjects.Find(id).WebSiteId;

        List<string> relatedTypes = new List<string>(relatedWebObjectTypes.Split(','));
        var resultData = (from w in db.WebObjects
                          where w.Id == id
                          from rw in w.RelatedWebObjects
                          select rw).ToList();

        result.Data = resultData.Where(w => relatedTypes.Contains(w.GetType().BaseType.Name) == true).Select(w => new { Id = w.Id, Type = w.GetType().BaseType.Name }).ToList();//w.Id).Select(w => w.GetType().BaseType.Name).ToList();
        result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
        return result;
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.