I have to use lucene.net 2.9.2.2 with NHibernate 3.0. I have started to edit this old code:
public void BuildSearchIndex()
{
FSDirectory entityDirectory = null;
IndexWriter writer = null;
var entityType = typeof(MappedSequence);
var indexDirectory = new DirectoryInfo(GetIndexDirectory());
if (indexDirectory.Exists)
{
indexDirectory.Delete(true);
}
try
{
entityDirectory = FSDirectory.GetDirectory(Path.Combine(indexDirectory.FullName, entityType.Name), true);
writer = new IndexWriter(entityDirectory, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), true, IndexWriter.MaxFieldLength.UNLIMITED);
}
finally
{
if (entityDirectory != null)
{
entityDirectory.Close();
}
if (writer != null)
{
writer.Close();
}
}
IFullTextSession fullTextSession = Search.CreateFullTextSession(this.Session);
// Iterate through Suppliers and add them to Lucene's index
foreach (MappedSequence instance in Session.CreateCriteria(typeof(MappedSequence)).List<MappedSequence>())
{
fullTextSession.Index(instance);
}
}
private string GetIndexDirectory()
{
INHSConfigCollection nhsConfigCollection = CfgHelper.LoadConfiguration();
string property = nhsConfigCollection.DefaultConfiguration.Properties["hibernate.search.default.indexBase"];
var fi = new FileInfo(property);
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fi.Name);
}
to build the index. The line:
FSDirectory.GetDirectory(Path.Combine(indexDirectory.FullName, entityType.Name), true);
still uses obsolete code. Could anyone be so kind and point out the necessary change. Thanks.
Christian
PS
Try using FSDirectory.Open(path) instead.
Related
I'm having real difficulty with EF Core with a Web API project I'm working... to me EF Core is not intuitive at all. I'm in a disconnected environment and I'm trying to update Sudoku games. EF Core is spending more time deleting connections between users and their apps and roles than in updating the game. How do I disable delete statements in an update? There is no reason for deletes, I don't need them. How do I stop them?
The method is as follows, the game is loaded as a graph and my understanding is this code should change everything tracked to modified or added. To me it seems like EF Core is going out of it's way to delete things... this makes no sense. I never instructed it to delete anything:
async public Task<IRepositoryResponse> Update(TEntity entity)
{
var result = new RepositoryResponse();
try
{
dbSet.Update(entity);
context.ChangeTracker.TrackGraph(entity,
e => {
var dbEntry = (IEntityBase)e.Entry.Entity;
if (dbEntry.Id != 0)
{
e.Entry.State = EntityState.Modified;
}
else
{
e.Entry.State = EntityState.Added;
}
});
await context.SaveChangesAsync();
result.Success = true;
result.Object = entity;
return result;
}
catch (Exception exp)
{
result.Success = false;
result.Exception = exp;
return result;
}
}
Well, I found a work around but it is the equivalent to the fixing your bike with bubblegum and tape. It's ugly... but it works. Before I save the game I create a list of all associated apps and roles and then recreate and resave the values after await context.SaveChangesAsync();. The code is listed below:
async public Task<IRepositoryResponse> Update(TEntity entity)
{
var result = new RepositoryResponse();
try
{
entity.DateUpdated = DateTime.UtcNow;
context.Games.Update(entity);
context.ChangeTracker.TrackGraph(entity,
e => {
var dbEntry = (IEntityBase)e.Entry.Entity;
if (dbEntry.Id != 0)
{
e.Entry.State = EntityState.Modified;
}
else
{
e.Entry.State = EntityState.Added;
}
});
var apps = new List<App>();
var roles = new List<Role>();
foreach (var userApp in entity.User.Apps)
{
apps.Add(userApp.App);
}
foreach (var userRole in entity.User.Roles)
{
roles.Add(userRole.Role);
}
await context.SaveChangesAsync();
foreach (var app in apps)
{
userAppDbSet.Add(new UserApp(entity.UserId, app.Id));
}
foreach (var role in roles)
{
userRoleDbSet.Add(new UserRole(entity.UserId, role.Id));
}
await context.SaveChangesAsync();
result.Success = true;
result.Object = entity;
return result;
}
catch (Exception exp)
{
result.Success = false;
result.Exception = exp;
return result;
}
}
There has to be a better way of doing this? The full app can be found here, can someone tell me a better way of setting this up:
https://github.com/Joseph-Anthony-King/SudokuCollective
I am trying to update the "Modified By" field based on a text field called "Prepared By", which contains the name of a user. I've created a pre-operation plug-in to do this and believe I am close to done. However, the "Modified By" field is still not successfully getting updated. I am relatively new to coding and CRM, and could use some help modifying the code and figuring out how I can get this to work.
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Linq;
namespace TimClassLibrary1.Plugins
{
public class CreateUpdateContact : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
var tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
var service = factory.CreateOrganizationService(context.UserId);
tracingService.Trace("Start plugin");
tracingService.Trace("Validate Target");
if (!context.InputParameters.Contains("Target") || !(context.InputParameters["Target"] is Entity))
return;
tracingService.Trace("Retrieve Target");
var target = (Entity)context.InputParameters["Target"];
String message = context.MessageName.ToLower();
SetCreatedByAndModifiedBy(tracingService, service, target, message);
}
private void SetCreatedByAndModifiedBy(ITracingService tracingService, IOrganizationService service, Entity target, string message)
{
tracingService.Trace("Start SetPriceList");
tracingService.Trace("Validate Message is Create or Update");
if (!message.Equals("create", StringComparison.OrdinalIgnoreCase) && !message.Equals("update", StringComparison.OrdinalIgnoreCase))
return;
tracingService.Trace("Retrieve Attributes");
var createdByReference = target.GetAttributeValue<EntityReference>("new_createdby");
var modifiedByReference = target.GetAttributeValue<EntityReference>("new_modifiedby");
tracingService.Trace("Retrieve And Set User for Created By");
RetrieveAndSetUser(tracingService, service, target, createdByReference, "createdby");
tracingService.Trace("Retrieve And Set User for Modified By");
RetrieveAndSetUser(tracingService, service, target, modifiedByReference, "modifiedby");
}
private void RetrieveAndSetUser(ITracingService tracingService, IOrganizationService service, Entity target, EntityReference reference, string targetAttribute)
{
tracingService.Trace("Validating Reference");
if (reference == null)
return;
tracingService.Trace("Retrieving and Validating User");
var user = RetrieveUserByName(service, reference.Name, new ColumnSet(false));
if (user == null)
return;
tracingService.Trace("Setting Target Attribute");
target[targetAttribute] = user.ToEntityReference();
}
private Entity RetrieveUserByName(IOrganizationService service, string name, ColumnSet columns)
{
var query = new QueryExpression
{
EntityName = "systemuser",
ColumnSet = columns,
Criteria = new FilterExpression
{
FilterOperator = LogicalOperator.And,
Conditions =
{
new ConditionExpression
{
AttributeName = "fullname",
Operator = ConditionOperator.Equal,
Values = { name }
}
}
}
};
var retrieveResponse = service.RetrieveMultiple(query);
if (retrieveResponse.Entities.Count == 1)
{
return retrieveResponse.Entities.FirstOrDefault();
}
else
{
return null;
}
}
}
}
If you do get use from method Retreiveusernyname then you have to use below code
target[“modifiedby”] = new EntityRefrence(user.logicalname,user.id);
I don't see anything obviously wrong with your update, however you are taking a complicated and unnecessary step with your RetrieveUserByName() method. You already have EntityReference objects from your new_createdby and new_modifiedby fields, you can simply assign those to the target:
if (message.Equals("create", StringComparison.OrdinalIgnoreCase))
{
target["createdby"] = target["new_createdby];
}
else if (message.Equals("update", StringComparison.OrdinalIgnoreCase))
{
target["modifiedby"] = target["new_modifiedby];
}
If new_createdby and new_modifiedby are not entity references, then that would explain why your existing code does not work, if they are, then use my approach.
I do an example with signalR. But it doesn't function because of one mistake.
The one mistake (can not convert type system.threading.tasks.task< object> to string) is in this line:
return context.Clients.All.RecieveNotification(simple);
It is at the bottom of the code you can see below.
Below you see the method I wrote. There I do a connection with the database and get the content with a command/query.
Then a few checks and also SqlDependency.
public string SendNotifications()
{
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
string query = "SELECT eintrag FROM [dbo].[simple_column]";
connection.Open();
using (SqlCommand command = new SqlCommand(query, connection))
{
command.Notification = null;
DataTable dt = new DataTable();
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
if (connection.State == ConnectionState.Closed)
connection.Open();
var reader = command.ExecuteReader();
dt.Load(reader);
if (dt.Rows.Count > 0)
{
simple = dt.Rows[0]["eintrag"].ToString();
}
}
}
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
return context.Clients.All.RecieveNotification(simple);
}
And here I use the function:
var notifications = $.connection.notificationHub;
notifications.client.recieveNotification = function (simple) {
// Add the message to the page.
$('#dbMessage').text(simple);
};
I hope you can help me.
Thanks.
I tried to find an answer through the related questions I got but I didn't see the same situation I have now. I a beginner with this framework.
The thing is that in the DB the TopicFeedbackType is always referred but TopicNavigatedUrl and Product are always inserted event if I attach the entity. What am I doing wrong? I attach the found entity to the correct entity set name. The entity gets attached. I noticed that before the p_TopicQuickFb have one of its property updated by an attached entity, its EntityKey is null, but when the currentNavUrl(for example) is set, the EntityKey of p_TopicQuickFb is not null anymore. Its value is "EntitySet=TopicQuickFeedbacks" but there is no id.
I am really lost in there.
public void AddTopicQuickFeedback(TopicQuickFeedback p_TopicQuickFb, string p_SessionID)
{
TopicFeedbackType currentType = this.GetTopicFeedbackType(p_TopicQuickFb.TopicFeedbackType.FeedbackType);
bool currentTypeAttached = false;
TopicNavigatedUrl currentNavUrl = this.GetTopicNavigatedUrl(p_TopicQuickFb.TopicNavigatedUrl.Url);
bool currentNavUrlAttached = false;
Product currentProduct = this.GetProduct(p_TopicQuickFb.Product.Name, p_TopicQuickFb.Product.MajorVersion, p_TopicQuickFb.Product.MinorVersion);
bool currentProductAttached = false;
using (COHFeedbackEntities context = GetObjectContext())
{
TopicFeedback tf = GetTopicFeedback(p_SessionID, context);
if (tf != null)
{
if (currentType != null)
{
p_TopicQuickFb.TopicFeedbackType = null;
context.AttachToOrGet<TopicFeedbackType>("TopicFeedbackTypes", ref currentType);
currentTypeAttached = true;
p_TopicQuickFb.TopicFeedbackType = currentType;
}
if (currentNavUrl != null)
{
p_TopicQuickFb.TopicNavigatedUrl = null;
context.AttachToOrGet<TopicNavigatedUrl>("TopicNavigatedUrls", ref currentNavUrl);
currentNavUrlAttached = true;
p_TopicQuickFb.TopicNavigatedUrl = currentNavUrl;
}
if (currentProduct != null)
{
p_TopicQuickFb.Product = null;
context.AttachToOrGet<Product>("Products", ref currentProduct);
currentProductAttached = true;
p_TopicQuickFb.Product = currentProduct;
}
tf.TopicQuickFeedbacks.Add(p_TopicQuickFb);
context.SaveChanges();
context.Detach(tf);
if (currentNavUrlAttached)
{
context.TopicNavigatedUrls.Detach(currentNavUrl);
}
if (currentProductAttached)
{
context.Products.Detach(currentProduct);
}
if (currentTypeAttached)
{
context.TopicFeedbackTypes.Detach(currentType);
}
}
}
}
I found the method in this post : Is is possible to check if an object is already attached to a data context in Entity Framework?
public static void AttachToOrGet<T>(this System.Data.Objects.ObjectContext context, string entitySetName, ref T entity)
where T : IEntityWithKey
{
System.Data.Objects.ObjectStateEntry entry;
// Track whether we need to perform an attach
bool attach = false;
if (
context.ObjectStateManager.TryGetObjectStateEntry
(
context.CreateEntityKey(entitySetName, entity),
out entry
)
)
{
// Re-attach if necessary
attach = entry.State == EntityState.Detached;
// Get the discovered entity to the ref
entity = (T)entry.Entity;
}
else
{
// Attach for the first time
attach = true;
}
if (attach)
{
context.AttachTo(entitySetName, entity);
}
}
Test method:
User user = new User(true, false, false);
string commentStr = "This is my comment";
Product product = new Product("ProductName", 7, 0);
TopicFeedbackComment commFeedback = new TopicFeedbackComment(commentStr, new TopicNavigatedUrl("http://testurl.com/test0"), product);
TopicFeedback feedback = new TopicFeedback(sessionID, user, FeedbackState.New);
provider.AddTopicFeedback(feedback);
TopicFeedback addedFeedback = provider.RetrieveTopicFeedback(sessionID);
provider.AddTopicFeedbackComment(commFeedback, sessionID);
Running this again and again do just INSERT to the
Can't post images so I can provide schema it if necessary.
My answer is in my last comment. I found it by myself.
If someone would like to comment why it's working this way it would be nice! :)
Hi I was wondering if EntityReference.Load method includes
If Not ref.IsLoaded Then ref.Load()
My question is basically:
Dim person = Context.Persons.FirstOrDefault
person.AddressReference.Load()
person.AddressReference.Load() 'Does it do anything?
It does Load again. I verified this by Profiler and it shown two queries. Default merge option is MergeOption.AppendOnly and it doesn't prevent from querying again. Code from Reflector:
public override void Load(MergeOption mergeOption)
{
base.CheckOwnerNull();
ObjectQuery<TEntity> query = base.ValidateLoad<TEntity>(mergeOption, "EntityReference");
base._suppressEvents = true;
try
{
List<TEntity> collection = new List<TEntity>(RelatedEnd.GetResults<TEntity>(query));
if (collection.Count > 1)
{
throw EntityUtil.MoreThanExpectedRelatedEntitiesFound();
}
if (collection.Count == 0)
{
if (base.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One)
{
throw EntityUtil.LessThanExpectedRelatedEntitiesFound();
}
if ((mergeOption == MergeOption.OverwriteChanges) || (mergeOption == MergeOption.PreserveChanges))
{
EntityKey entityKey = ObjectStateManager.FindKeyOnEntityWithRelationships(base.Owner);
EntityUtil.CheckEntityKeyNull(entityKey);
ObjectStateManager.RemoveRelationships(base.ObjectContext, mergeOption, (AssociationSet) base.RelationshipSet, entityKey, (AssociationEndMember) base.FromEndProperty);
}
base._isLoaded = true;
}
else
{
base.Merge<TEntity>(collection, mergeOption, true);
}
}
finally
{
base._suppressEvents = false;
}
this.OnAssociationChanged(CollectionChangeAction.Refresh, null);
}
Just for reference for anyone else finding the accepted answer, here is the extension method I created for my current project.
using System.Data.Objects.DataClasses;
namespace ProjectName
{
public static class EntityFrameworkExtensions
{
public static void EnsureLoaded<TEntity>(this EntityReference<TEntity> reference)
where TEntity : class, IEntityWithRelationships
{
if (!reference.IsLoaded)
reference.Load();
}
}
}
And usage:
Patient patient = // get patient
patient.ClinicReference.EnsureLoaded();
patient.Clinic.DoStuff();