Thinking of trying to use Petapoco.Fetch where member "content" is an c# object.
"Content" member is byte[] member which I store in cache og want to retrieve specially .. not from database.
So:
SQL = "select * table.FundDocument";
List<FundDocument> fundDocuments = new List<FundDocument>();
fundDocuments = database.Fetch<FundDocument>(SQL)
.IgnoreORExcept(FundDocument.content = GetDocumentFromCache(id));
So petapoco object would fetch everything except the member "content", it would fetch that from the function GetDocumentFromCache();
Is this possible?
You can use ExplicitColumns in your POCO and exclude the property from being retrieved or you can name it different, so PetaPoco don't retrieve it.
Related
I'm using early-bound entities, generated by CrmSvcUtil, and I'm testing the SDK by retrieving an account entity:-
var account = myContext.AccountSet.FirstOrDefault(o => o.Id == Guid.Parse("..."));
(BTW is there an easier way to retrieve an entity by ID?!)
Looking at the account object that is returned, I can see various properties of type OptionSetValue (e.g. "PreferredContactMethodCode"). How do I get the actual item from this OptionSetValue object?
Similarly, there are numerous properties of type EntityReference, which contains an Id and LogicalName (the entity name I presume). How can I populate such a property - is it one of the Get... methods? And do these have to be called separately, or is it possible to "pre-fetch" certain relationships as part of the initial query that retrieves the account entity?
Similarly with the various IEnumerable<> properties (which presumably correspond to 1-M entity relationships), e.g. a property called "opportunity_customer_accounts" of type IEnumerable. How do I populate one of these properties? And (again) does this have to be done as a separate query/method call, or can it be "pre-fetched"?
Retrieve
I'm not really sure how much simpler the retrieve operation could get but for a single record the user of the context is probably overkill. So you could retrieve a specific record where you know directly with the IOrganizationService:
account = service.Retrieve("account", Guid.Parse("..."), new ColumnSet(true));
Option Set Labels
For the OptionSet labels you can look at my answer here: How to get the option set from a field in an entity in CRM 2011 using crm sdk and C#.
If you need the label for multiple OptionSet's on an entity you may want to just retrieve the Entity's metadata once (http://srinivasrajulapudi.blogspot.com/2012/01/retrieve-entity-metadata-in-crm-2011.html):
string entityName ="contact";
// Get the metadata for the currently list's entity
// This metadata is used to create a "Property Descriptor Collection"
RetrieveEntityRequest mdRequest = new RetrieveEntityRequest ( )
{ EntityFilters = EntityFilters.All,
LogicalName = entityName,
RetrieveAsIfPublished = false
};
// Execute the request
RetrieveEntityResponse entityResponse = ( RetrieveEntityResponse ) this.ServiceProxy.Execute ( mdRequest );
EntityMetadata entityData = entityResponse.EntityMetadata;
//To Get Option Set Data
var preferdList= ( entityData.Attributes.Where ( p => p.LogicalName == "preferredcontactmethodcode" ) ).ToList ( ).FirstOrDefault ( ); ;
if ( preferdList != null ) {
PicklistAttributeMetadata optionList= preferdList as PicklistAttributeMetadata;
OptionSetMetadata opValues= optionList.OptionSet;
foreach ( var op in opValues.Options ) {
preferedMethod.Add ( new OptionSet { Value = op.Value.Value, Text = op.Label.LocalizedLabels[0].Label.ToString() } );
}
}
EntityReference()
To set an EntityReference typed field:
account.primarycontact = new EntityReference("contact", Guide.Parse("..."));
If they have a value and you requested the column in your ColumnSet() they should be populated, so I'm not really sure I understand your question. If you mean, you want the full record then you need to do a service.Retrieve(...) for the record.
Related Entities (i.e., opportunity_customer_accounts)
This is where using an OrganizationServiceContext makes life easier (https://msdn.microsoft.com/en-us/library/gg695791.aspx):
context.LoadProperty(contact, "transactioncurrency_contact");
// read related entity dynamically
var currency = contact.GetRelatedEntity("transactioncurrency_contact");
Console.WriteLine(currency.GetAttributeValue("currencyname"));
// read related entity statically
var currencyStatic = contact.transactioncurrency_contact;
Console.WriteLine(currencyStatic.CurrencyName);
If you are not using an OrganizationServiceContext you can try using a QueryExpression using LinkedEntities, although I've never done this to populate an early-bound entity so I don't know if it works (perhaps someone will add a comment with the answer.)
A small briefing on what I am trying to do.
I have three tables Content(contentId, body, timeofcreation), ContentAttachmentMap(contentId, attachmentId) and Attachment(attachmentId, resourceLocation).
The reason I adopted to create the mapping table because in future application the attachment can also be shared with different content.
Now I am using HQL to get data. My objectives is as follows:
Get All contents with/without Attachments
I have seen some examples in the internet like you can create an objective specific class (not POJO) and put the attribute name from the select statement within its constructor and the List of that Class object is returned.
For e.g. the HQL will be SELECT new com.mydomain.myclass(cont.id, cont.body) ..... and so on.
In my case I am looking for the following SELECT new com.mydomain.contentClass(cont.id, cont.body, List<Attachment>) FROM ...`. Yes, I want to have the resultList contain contentid, contentbody and List of its Attachments as a single result List item. If there are no attachments then it will return (cont.id, contentbody, null).
Is this possible? Also tell me how to write the SQL statements.
Thanks in advance.
I feel you are using Hibernate in a fundamentally wrong way. You should use Hibernate to view your domain entity, not to use it as exposing the underlying table.
You don't need to have that contentClass special value object for all these. Simply selecting the Content entity serves what you need.
I think it will be easier to have actual example.
In your application, you are not seeing it as "3 tables", you should see it as 2 entities, which is something look like:
#Entity
public class Content {
#Id
Long id;
#Column(...)
String content;
#ManyToMany
#JoinTable(name="ContentAttachmentMap")
List<Attachment> attachments;
}
#Entity
public class Attachment {
#Id
Long id;
#Column(...)
String resourceLocation
}
And, the result you are looking for is simply the result of HQL of something like
from Content where attachments IS EMPTY
I believe you can join fetch too in order to save DB access:
from Content c left join fetch c.attachments where c.attachments IS EMPTY
I am working on NET MVC 3.0 and Nhibernate 3.0. I want to fetch only one property from database to an object.
For instance, suppose I have a class Module. I want to select all the names from module table (like select modulename from module query) and an prepare a list of module objects which have only name. All other properties can be null.
I tried this using QueryOver API:
IQueryOver<ProjectModule> module = session.QueryOver<ProjectModule>()
.Select(a=>a.Name)
.TransformUsing(
NHibernate.Transform.Transformers.AliasToBean<ProjectModule>());
pm = module.List<ProjectModule>();
pm is IList<ProjectModule> type.
Transaction gets committed successfully. No error occurred, but I get a list of module objects with all properties = null. Module name null, module id null etc.
I checked what query is executing on SQL using NUnit and got this: SELECT this_Name as y0_ FROM ProjectModule this_.
To be more accurate create a DTO object, assume ProjectModuleDto, that will contain only the Name. It's not a good practice to use the the domain object with uninitialized values through your code, cause it creates confusions of filled data in various scenarious.
And the fllowing code will do the trick - populate the list of DTOs: ProjectModuleDto with correct Name of project module from database:
ProjectModuleDto projectModuleDto = null;
IQueryOver<ProjectModule> module = session.QueryOver<ProjectModule>()
.SelectList(
list=>list.Select(a => a.Name).WithAlias(() => projectModuleDto.Name)
)
TransformUsing(NHibernate.Transform.Transformers.AliasToBean<ProjectModuleDto>());
pm = module.List<ProjectModuleDto>();
If you are fetching only a single property, you don't need to use transformers. Try to use a List<string> directly:
var moduleNames = session.QueryOver<ProjectModule>()
.Select(a => a.Name)
.List<string>();
Read more about QueryOver syntax on NHibernate blog.
Is this what you're looking for?
List<ProjectModule> result = new List<ProjectModule>();
session.QueryOver<ProjectModule>()
.Select(a => a.Name)
.ToList().ForEach(delegate(string mName)
{
result.Add(ProjectModule() { Name = mName });
});
I am trying to construct an SQL statement dynamically.
My context is created dynamically, using reflection finding classes deriving from EntityTypeConfiguration and adding them to DbModelBuilder.Configuration.
My EntityTypeConfiguration classes specify HasColumnName to map the Entity property name to db table column name, which I need to construct my SQL statement.
namespace MyDomain {
public class TestEntityConfig : EntityTypeConfiguration<TestEntity>{
Property("Name").HasColumnName("dbName");
}
}
From What I have researched, it seems I can get access to this information through MetadataWorkspace, which I can get to through ObjectContext.
I have managed to retrieve the the entity I am interested in with MetadataWorkspace.GetItem("MyDomain.TestEntity",DataSpace.OSpace), which gives me access to Properties, but none of the properties, of Properties, give me the name of the mapped db column, as specified with HasColumnName.
Also I am not clear what DataSpace.OSpace is and why my model is constructed in this space.
If Anyone can shed some light on this I would be grateful
UPDATE
Further to #Ladislav's comments. I discovered I can get the information as follows
For the class properties
ctx.MetadataWorkspace.GetItem<ClrEntityType>("MyDomain.TestEntity", DataSpace.OSpace)).Members
For the table properties
ctx.MetadataWorkspace.GetItem<EntityType>("CodeFirstDatabaseSchema.TestEntity",SSpace).Members
So given that I only know the type MyDomain.TestEntity and Memeber "Name". How would I go about to get "dbName". Can I always assume that my mapped class will be created in CodeFirstDatabaseSchema, om order to dynamically construct the identity to retrieve it from SSpace and how would I get to the correct Member in SSpace. Can I do something like
var memIndex = ctx.MetadataWorkspace.GetItem<ClrEntityType>("MyDomain.TestEntity", DataSpace.OSpace)).Members["Name"].Index;
var dbName = ctx.MetadataWorkspace.GetItem<EntityType>("CodeFirstDatabaseSchema.TestEntity",SSpace).Members[memIndex];
MetadataWorkspace contanis several containers specified by DataSpace. Interesting for you are:
CSpace - description of conceptual model (this should contain properties)
CSSpace - mapping of conceptual model to storage model (this should contain how classes / properties are mapped to tables / columns)
I am trying to retrieve the attribute name and type that exist in an entity, Dynamic Entity to be precise. I have the following code.
DynamicEntity contactEntity = new DynamicEntity();
contactEntity.Name = EntityName.contact.ToString();
Property t = null;
foreach (Property prop_Test in contactEntity.Properties)
{
Response.Write("<br/>Name : " + prop_Test.Name.ToString());
}
I am getting the properties count as 0.
Is it mandatory for me to pass an id to the contact entity. Because i am trying to map attributes from the entity to the attributes i get from an excel file. The end user themselves would be doing the mapping so all i need are the attribute name and type and nothing else. For instance in SQL we have the query
SELECT * FROM TABLE_NAME WHERE 1 <> 1
This query basically returns an empty resultset with only the fieldnames. That is what i am looking for here. Is it even possible ?
In your example above, the dynamic entity does not have any properties set on it. The dynamic entity is a special type in MS CRM that is used when you do not know the CRM type until runtime. If you add properties to the dynamic entity and run your example, you will get however many properties returned that you define.
In order to get the contact attributes, you will need to reference the CRM Metadata Service as explained in the SDK.
There is an example within this download in the HowTo section that shows how to get out the entity and attribute metadata.