|
How did you ever find that? And how did you figure out how it works from the incredibly sparse MSDN documentation? I found what looks like a decent tutorial, of course not by MS, which I'll have to read through now.
Latest Article - Contextual Data Explorer
Learning to code with python is like learning to swim with those little arm floaties. It gives you undeserved confidence and will eventually drown you. - DangerBunny
Artificial intelligence is the only remedy for natural stupidity. - CDP1802
|
|
|
|
|
|
Looks like stuff for an upcoming article
|
|
|
|
|
A tip at best... Between work, my own business, study for Azure exams, and something that more or less resembles a social life I have zero time to write at the moment
|
|
|
|
|
Looks like we are in the same boat again (don't know if that's good English), time keeps on slippin, slippin, into the future ...
|
|
|
|
|
That's what I was gonna suggest - make it a tip/trick.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
Is the additional info coming from the same entity. If so, why not just add it to TModel and get it with the first select?
"Time flies like an arrow. Fruit flies like a banana."
|
|
|
|
|
It's actually more like context.Set<TEntity>().Select(e => new TModel { ... }).ToList();
And now I want to "open up" the selector, not completely replace it (because that will result in quite some duplicated code), but add to it.
I have x TEntity classes that share stuff like Id , Name , Active and even a details table reference, that go nicely into the common selector.
But some also have one or two properties that aren't shared by the others.
Other than those few properties all logic is exactly the same.
I currently have five web pages that use the exact same code in the back-end (save for those few properties)
Took me about twenty to thirty hours to write the first page as abstract as it is and then it took me an hour to add three more and I just spend four hours for the fifth, for which I had to add this
|
|
|
|
|
You could do something with the Join method but I would derive an new model from TModel.
There are a number of ways to do what you want, but without seeing your existing code, I can't suggest the best way. You really want this to only make one call to the database, so getting the right projection in the first place is important.
|
|
|
|
|
Matthew@Home wrote: but without seeing your existing code, I can't suggest the best way Well, I wasn't really asking for suggestions, but I appreciate the help
Here's the situation:
I've got a couple of entities.
public class EntityA : IMyInterface
{
public int Id { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
public List<DetailA> Details { get; set; }
}
public class EntityB : IMyInterface
{
public int Id { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
public List<DetailB> Details { get; set; }
}
public class EntityC : IMyInterface
{
public int Id { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
public string SomeOtherProperty { get; set; }
public string AnotherProperty { get; set; }
public List<DetailC> Details { get; set; }
}
Then I've got this model:
public class SharedModel
{
public int Id { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
public List<SharedDetailModel> Details { get; set; }
} And a query for all entities:
public TModel GetModels<TModel, TEntity>()
where TModel : SharedModel, new()
where TEntity : class, IMyInterface, new()
{
context.Set<TEntity>()
.Where(...)
.Select(e => new TModel
{
Id = e.Id,
Name = e.Name,
Active = e.Active,
Details = e.Details.Select(...)
}).ToList();
} So this works for everything except SomeOtherProperty and AnotherProperty for EntityC .
So I somehow want to inject them into the selector.
Expression<Func<TEntity, TModel>> baseSelect = e => new TModel
{
Id = e.Id,
Name = e.Name,
Active = e.Active,
Details = e.Details.Select(...)
};
Expression<Func<TEntity, TModel>> additionalSelect = e => new MyCustomModel
{
SomeOtherProperty = e.SomeOtherProperty,
AnotherProperty = e.AnotherProperty
}; And then merge the two trees...
MemberInitExpression baseSelectBody = (MemberInitExpression)baseSelect.Body;
MemberInitExpression additionalSelectBody = (MemberInitExpression)additionalSelect.Body;
ParameterExpression parameter = Expression.Parameter(typeof(TEntity), "e");
IEnumerable<MemberBinding> bindings = baseSelectBody.Bindings.Union(additionalSelectBody.Bindings);
MemberInitExpression init = Expression.MemberInit(Expression.New(typeof(TModel)), bindings);
Expression newInit = new ExpressionParameterSwitcher(parameter).Visit(init);
exp = Expression.Lambda<Func<TEntity, TModel>>(newInit, parameter); And now it's easy, just do context.Set<TEntity>().Select(exp);
Guess I've just pretty much written a tip...
|
|
|
|
|
Bookmarked.
This might come in handy if i ever rebuild my caching class.
I just wish you could've given the thread a more descriptive name, next time I see it among the bookmarks I won't have a clue what it is about.
|
|
|
|
|
|
That's also very familiar
|
|
|
|
|
Yip.. something that should be fast takes forever. Uhg
And then having to explain to management why...
|
|
|
|
|
It seems to me that the 'The Machine Learning and Artificial Intelligence Challenge' closed 24 hours earlier...
@chris-maunder?
Skipper: We'll fix it.
Alex: Fix it? How you gonna fix this?
Skipper: Grit, spit and a whole lotta duct tape.
modified 4-Mar-18 3:59am.
|
|
|
|
|
I generally refer to those people in other time zones as 'Time Bandits'
|
|
|
|
|
I hope you are aware that there are millions of 'time bandits' all around you?
Skipper: We'll fix it.
Alex: Fix it? How you gonna fix this?
Skipper: Grit, spit and a whole lotta duct tape.
|
|
|
|
|
We refer to them as foreigners.
|
|
|
|
|
Quote: You're as cold as ice
You're willing to sacrifice our love
You never take advice
Someday you'll pay the price, I know
|
|
|
|
|
That song takes me back...
It was on the first cassette that I bought for my brand-new Walkman. How time flies.
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack.
--Winston Churchill
|
|
|
|
|
Foreigner was in the 'hitparade' in Holland for weeks, must have been in 1977, and I still hear it regularly on the radio ...
So don't accuse us of having anything against Foreigner
|
|
|
|
|
Sounds like me ...
|
|
|
|
|
Now now, cheer up, you can't be that bad, remember that you were never banned from CodeProject !
Did that cheer you up a little
|
|
|
|
|
|
Speaking of which, the world is going to hell and it's all the fault of those darn foreigners!
There are 7 billion people on earth and do you know how many of them are foreigners!?
|
|
|
|